diff options
| author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-18 22:37:57 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-18 22:37:57 -0500 |
| commit | 0f36b018b2e314d45af86449f1a97facb1fbe300 (patch) | |
| tree | b6a8f59834c3de2ca83e680007b8165de0097d47 | |
| parent | 648bf4fb21f5ce993403901ed82399abaa150b63 (diff) | |
| parent | 47c886b3123a335f0622136e021e7691d60d742c (diff) | |
Merge master.kernel.org:/pub/scm/linux/kernel/git/sfrench/cifs-2.6
| -rw-r--r-- | fs/cifs/CHANGES | 10 | ||||
| -rw-r--r-- | fs/cifs/README | 12 | ||||
| -rw-r--r-- | fs/cifs/cifs_debug.c | 51 | ||||
| -rw-r--r-- | fs/cifs/cifs_fs_sb.h | 5 | ||||
| -rw-r--r-- | fs/cifs/cifsacl.h | 38 | ||||
| -rw-r--r-- | fs/cifs/cifsencrypt.c | 55 | ||||
| -rw-r--r-- | fs/cifs/cifsfs.c | 28 | ||||
| -rw-r--r-- | fs/cifs/cifsfs.h | 2 | ||||
| -rw-r--r-- | fs/cifs/cifsglob.h | 18 | ||||
| -rw-r--r-- | fs/cifs/cifspdu.h | 97 | ||||
| -rw-r--r-- | fs/cifs/cifsproto.h | 23 | ||||
| -rw-r--r-- | fs/cifs/cifssmb.c | 294 | ||||
| -rw-r--r-- | fs/cifs/connect.c | 89 | ||||
| -rw-r--r-- | fs/cifs/dir.c | 8 | ||||
| -rw-r--r-- | fs/cifs/file.c | 73 | ||||
| -rw-r--r-- | fs/cifs/inode.c | 9 | ||||
| -rw-r--r-- | fs/cifs/misc.c | 17 | ||||
| -rw-r--r-- | fs/cifs/readdir.c | 17 | ||||
| -rw-r--r-- | fs/cifs/rfc1002pdu.h | 4 | ||||
| -rw-r--r-- | fs/cifs/transport.c | 40 | ||||
| -rw-r--r-- | fs/cifs/xattr.c | 22 |
21 files changed, 729 insertions, 183 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 943ef9b82244..d335015473a5 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
| @@ -1,3 +1,11 @@ | |||
| 1 | Version 1.40 | ||
| 2 | ------------ | ||
| 3 | Use fsuid (fsgid) more consistently instead of uid (gid). Improve performance | ||
| 4 | of readpages by eliminating one extra memcpy. Allow update of file size | ||
| 5 | from remote server even if file is open for write as long as mount is | ||
| 6 | directio. Recognize share mode security and send NTLM encrypted password | ||
| 7 | on tree connect if share mode negotiated. | ||
| 8 | |||
| 1 | Version 1.39 | 9 | Version 1.39 |
| 2 | ------------ | 10 | ------------ |
| 3 | Defer close of a file handle slightly if pending writes depend on that handle | 11 | Defer close of a file handle slightly if pending writes depend on that handle |
| @@ -7,6 +15,8 @@ Fix SFU style symlinks and mknod needed for servers which do not support the | |||
| 7 | CIFS Unix Extensions. Fix setfacl/getfacl on bigendian. Timeout negative | 15 | CIFS Unix Extensions. Fix setfacl/getfacl on bigendian. Timeout negative |
| 8 | dentries so files that the client sees as deleted but that later get created | 16 | dentries so files that the client sees as deleted but that later get created |
| 9 | on the server will be recognized. Add client side permission check on setattr. | 17 | on the server will be recognized. Add client side permission check on setattr. |
| 18 | Timeout stuck requests better (where server has never responded or sent corrupt | ||
| 19 | responses) | ||
| 10 | 20 | ||
| 11 | Version 1.38 | 21 | Version 1.38 |
| 12 | ------------ | 22 | ------------ |
diff --git a/fs/cifs/README b/fs/cifs/README index e5d09a2fc7a5..b0070d1b149d 100644 --- a/fs/cifs/README +++ b/fs/cifs/README | |||
| @@ -436,7 +436,17 @@ A partial list of the supported mount options follows: | |||
| 436 | SFU does). In the future the bottom 9 bits of the mode | 436 | SFU does). In the future the bottom 9 bits of the mode |
| 437 | mode also will be emulated using queries of the security | 437 | mode also will be emulated using queries of the security |
| 438 | descriptor (ACL). | 438 | descriptor (ACL). |
| 439 | 439 | sec Security mode. Allowed values are: | |
| 440 | none attempt to connection as a null user (no name) | ||
| 441 | krb5 Use Kerberos version 5 authentication | ||
| 442 | krb5i Use Kerberos authentication and packet signing | ||
| 443 | ntlm Use NTLM password hashing (default) | ||
| 444 | ntlmi Use NTLM password hashing with signing (if | ||
| 445 | /proc/fs/cifs/PacketSigningEnabled on or if | ||
| 446 | server requires signing also can be the default) | ||
| 447 | ntlmv2 Use NTLMv2 password hashing | ||
| 448 | ntlmv2i Use NTLMv2 password hashing with packet signing | ||
| 449 | |||
| 440 | The mount.cifs mount helper also accepts a few mount options before -o | 450 | The mount.cifs mount helper also accepts a few mount options before -o |
| 441 | including: | 451 | including: |
| 442 | 452 | ||
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index 22a444a3fe4c..f4124a32bef8 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c | |||
| @@ -219,6 +219,10 @@ cifs_stats_write(struct file *file, const char __user *buffer, | |||
| 219 | 219 | ||
| 220 | if (c == '1' || c == 'y' || c == 'Y' || c == '0') { | 220 | if (c == '1' || c == 'y' || c == 'Y' || c == '0') { |
| 221 | read_lock(&GlobalSMBSeslock); | 221 | read_lock(&GlobalSMBSeslock); |
| 222 | #ifdef CONFIG_CIFS_STATS2 | ||
| 223 | atomic_set(&totBufAllocCount, 0); | ||
| 224 | atomic_set(&totSmBufAllocCount, 0); | ||
| 225 | #endif /* CONFIG_CIFS_STATS2 */ | ||
| 222 | list_for_each(tmp, &GlobalTreeConnectionList) { | 226 | list_for_each(tmp, &GlobalTreeConnectionList) { |
| 223 | tcon = list_entry(tmp, struct cifsTconInfo, | 227 | tcon = list_entry(tmp, struct cifsTconInfo, |
| 224 | cifsConnectionList); | 228 | cifsConnectionList); |
| @@ -276,6 +280,14 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset, | |||
| 276 | smBufAllocCount.counter,cifs_min_small); | 280 | smBufAllocCount.counter,cifs_min_small); |
| 277 | length += item_length; | 281 | length += item_length; |
| 278 | buf += item_length; | 282 | buf += item_length; |
| 283 | #ifdef CONFIG_CIFS_STATS2 | ||
| 284 | item_length = sprintf(buf, "Total Large %d Small %d Allocations\n", | ||
| 285 | atomic_read(&totBufAllocCount), | ||
| 286 | atomic_read(&totSmBufAllocCount)); | ||
| 287 | length += item_length; | ||
| 288 | buf += item_length; | ||
| 289 | #endif /* CONFIG_CIFS_STATS2 */ | ||
| 290 | |||
| 279 | item_length = | 291 | item_length = |
| 280 | sprintf(buf,"Operations (MIDs): %d\n", | 292 | sprintf(buf,"Operations (MIDs): %d\n", |
| 281 | midCount.counter); | 293 | midCount.counter); |
| @@ -389,8 +401,8 @@ static read_proc_t ntlmv2_enabled_read; | |||
| 389 | static write_proc_t ntlmv2_enabled_write; | 401 | static write_proc_t ntlmv2_enabled_write; |
| 390 | static read_proc_t packet_signing_enabled_read; | 402 | static read_proc_t packet_signing_enabled_read; |
| 391 | static write_proc_t packet_signing_enabled_write; | 403 | static write_proc_t packet_signing_enabled_write; |
| 392 | static read_proc_t quotaEnabled_read; | 404 | static read_proc_t experimEnabled_read; |
| 393 | static write_proc_t quotaEnabled_write; | 405 | static write_proc_t experimEnabled_write; |
| 394 | static read_proc_t linuxExtensionsEnabled_read; | 406 | static read_proc_t linuxExtensionsEnabled_read; |
| 395 | static write_proc_t linuxExtensionsEnabled_write; | 407 | static write_proc_t linuxExtensionsEnabled_write; |
| 396 | 408 | ||
| @@ -430,9 +442,9 @@ cifs_proc_init(void) | |||
| 430 | pde->write_proc = oplockEnabled_write; | 442 | pde->write_proc = oplockEnabled_write; |
| 431 | 443 | ||
| 432 | pde = create_proc_read_entry("Experimental", 0, proc_fs_cifs, | 444 | pde = create_proc_read_entry("Experimental", 0, proc_fs_cifs, |
| 433 | quotaEnabled_read, NULL); | 445 | experimEnabled_read, NULL); |
| 434 | if (pde) | 446 | if (pde) |
| 435 | pde->write_proc = quotaEnabled_write; | 447 | pde->write_proc = experimEnabled_write; |
| 436 | 448 | ||
| 437 | pde = create_proc_read_entry("LinuxExtensionsEnabled", 0, proc_fs_cifs, | 449 | pde = create_proc_read_entry("LinuxExtensionsEnabled", 0, proc_fs_cifs, |
| 438 | linuxExtensionsEnabled_read, NULL); | 450 | linuxExtensionsEnabled_read, NULL); |
| @@ -574,14 +586,13 @@ oplockEnabled_write(struct file *file, const char __user *buffer, | |||
| 574 | } | 586 | } |
| 575 | 587 | ||
| 576 | static int | 588 | static int |
| 577 | quotaEnabled_read(char *page, char **start, off_t off, | 589 | experimEnabled_read(char *page, char **start, off_t off, |
| 578 | int count, int *eof, void *data) | 590 | int count, int *eof, void *data) |
| 579 | { | 591 | { |
| 580 | int len; | 592 | int len; |
| 581 | 593 | ||
| 582 | len = sprintf(page, "%d\n", experimEnabled); | 594 | len = sprintf(page, "%d\n", experimEnabled); |
| 583 | /* could also check if quotas are enabled in kernel | 595 | |
| 584 | as a whole first */ | ||
| 585 | len -= off; | 596 | len -= off; |
| 586 | *start = page + off; | 597 | *start = page + off; |
| 587 | 598 | ||
| @@ -596,21 +607,23 @@ quotaEnabled_read(char *page, char **start, off_t off, | |||
| 596 | return len; | 607 | return len; |
| 597 | } | 608 | } |
| 598 | static int | 609 | static int |
| 599 | quotaEnabled_write(struct file *file, const char __user *buffer, | 610 | experimEnabled_write(struct file *file, const char __user *buffer, |
| 600 | unsigned long count, void *data) | 611 | unsigned long count, void *data) |
| 601 | { | 612 | { |
| 602 | char c; | 613 | char c; |
| 603 | int rc; | 614 | int rc; |
| 604 | 615 | ||
| 605 | rc = get_user(c, buffer); | 616 | rc = get_user(c, buffer); |
| 606 | if (rc) | 617 | if (rc) |
| 607 | return rc; | 618 | return rc; |
| 608 | if (c == '0' || c == 'n' || c == 'N') | 619 | if (c == '0' || c == 'n' || c == 'N') |
| 609 | experimEnabled = 0; | 620 | experimEnabled = 0; |
| 610 | else if (c == '1' || c == 'y' || c == 'Y') | 621 | else if (c == '1' || c == 'y' || c == 'Y') |
| 611 | experimEnabled = 1; | 622 | experimEnabled = 1; |
| 623 | else if (c == '2') | ||
| 624 | experimEnabled = 2; | ||
| 612 | 625 | ||
| 613 | return count; | 626 | return count; |
| 614 | } | 627 | } |
| 615 | 628 | ||
| 616 | static int | 629 | static int |
| @@ -620,8 +633,6 @@ linuxExtensionsEnabled_read(char *page, char **start, off_t off, | |||
| 620 | int len; | 633 | int len; |
| 621 | 634 | ||
| 622 | len = sprintf(page, "%d\n", linuxExtEnabled); | 635 | len = sprintf(page, "%d\n", linuxExtEnabled); |
| 623 | /* could also check if quotas are enabled in kernel | ||
| 624 | as a whole first */ | ||
| 625 | len -= off; | 636 | len -= off; |
| 626 | *start = page + off; | 637 | *start = page + off; |
| 627 | 638 | ||
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index f799f6f0e729..ad58eb0c4d6d 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h | |||
| @@ -24,9 +24,10 @@ | |||
| 24 | #define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */ | 24 | #define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */ |
| 25 | #define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */ | 25 | #define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */ |
| 26 | #define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */ | 26 | #define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */ |
| 27 | #define CIFS_MOUNT_POSIX_PATHS 0x40 /* Negotiate posix pathnames if possible. */ | 27 | #define CIFS_MOUNT_POSIX_PATHS 0x40 /* Negotiate posix pathnames if possible. */ |
| 28 | #define CIFS_MOUNT_UNX_EMUL 0x80 /* Network compat with SFUnix emulation */ | 28 | #define CIFS_MOUNT_UNX_EMUL 0x80 /* Network compat with SFUnix emulation */ |
| 29 | #define CIFS_MOUNT_NO_BRL 0x100 /* No sending byte range locks to srv */ | 29 | #define CIFS_MOUNT_NO_BRL 0x100 /* No sending byte range locks to srv */ |
| 30 | #define CIFS_MOUNT_CIFS_ACL 0x200 /* send ACL requests to non-POSIX srv */ | ||
| 30 | 31 | ||
| 31 | struct cifs_sb_info { | 32 | struct cifs_sb_info { |
| 32 | struct cifsTconInfo *tcon; /* primary mount */ | 33 | struct cifsTconInfo *tcon; /* primary mount */ |
diff --git a/fs/cifs/cifsacl.h b/fs/cifs/cifsacl.h new file mode 100644 index 000000000000..d0776ac2b804 --- /dev/null +++ b/fs/cifs/cifsacl.h | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | /* | ||
| 2 | * fs/cifs/cifsacl.h | ||
| 3 | * | ||
| 4 | * Copyright (c) International Business Machines Corp., 2005 | ||
| 5 | * Author(s): Steve French (sfrench@us.ibm.com) | ||
| 6 | * | ||
| 7 | * This library is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU Lesser General Public License as published | ||
| 9 | * by the Free Software Foundation; either version 2.1 of the License, or | ||
| 10 | * (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This library is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See | ||
| 15 | * the GNU Lesser General Public License for more details. | ||
| 16 | * | ||
| 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 | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | */ | ||
| 21 | |||
| 22 | #ifndef _CIFSACL_H | ||
| 23 | #define _CIFSACL_H | ||
| 24 | |||
| 25 | struct cifs_sid { | ||
| 26 | __u8 revision; /* revision level */ | ||
| 27 | __u8 num_subauths; | ||
| 28 | __u8 authority[6]; | ||
| 29 | __u32 sub_auth[4]; | ||
| 30 | /* next sub_auth if any ... */ | ||
| 31 | } __attribute__((packed)); | ||
| 32 | |||
| 33 | /* everyone */ | ||
| 34 | extern const struct cifs_sid sid_everyone; | ||
| 35 | /* group users */ | ||
| 36 | extern const struct cifs_sid sid_user; | ||
| 37 | |||
| 38 | #endif /* _CIFSACL_H */ | ||
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index fe2bb7c4c912..a2c24858d40f 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * fs/cifs/cifsencrypt.c | 2 | * fs/cifs/cifsencrypt.c |
| 3 | * | 3 | * |
| 4 | * Copyright (C) International Business Machines Corp., 2003 | 4 | * Copyright (C) International Business Machines Corp., 2005 |
| 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 |
| @@ -82,6 +82,59 @@ int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct TCP_Server_Info * server, | |||
| 82 | return rc; | 82 | return rc; |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | static int cifs_calc_signature2(const struct kvec * iov, int n_vec, | ||
| 86 | const char * key, char * signature) | ||
| 87 | { | ||
| 88 | struct MD5Context context; | ||
| 89 | |||
| 90 | if((iov == NULL) || (signature == NULL)) | ||
| 91 | return -EINVAL; | ||
| 92 | |||
| 93 | MD5Init(&context); | ||
| 94 | MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16); | ||
| 95 | |||
| 96 | /* MD5Update(&context,cifs_pdu->Protocol,cifs_pdu->smb_buf_length); */ /* BB FIXME BB */ | ||
| 97 | |||
| 98 | MD5Final(signature,&context); | ||
| 99 | |||
| 100 | return -EOPNOTSUPP; | ||
| 101 | /* return 0; */ | ||
| 102 | } | ||
| 103 | |||
| 104 | |||
| 105 | int cifs_sign_smb2(struct kvec * iov, int n_vec, struct TCP_Server_Info *server, | ||
| 106 | __u32 * pexpected_response_sequence_number) | ||
| 107 | { | ||
| 108 | int rc = 0; | ||
| 109 | char smb_signature[20]; | ||
| 110 | struct smb_hdr * cifs_pdu = iov[0].iov_base; | ||
| 111 | |||
| 112 | if((cifs_pdu == NULL) || (server == NULL)) | ||
| 113 | return -EINVAL; | ||
| 114 | |||
| 115 | if((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0) | ||
| 116 | return rc; | ||
| 117 | |||
| 118 | spin_lock(&GlobalMid_Lock); | ||
| 119 | cifs_pdu->Signature.Sequence.SequenceNumber = | ||
| 120 | cpu_to_le32(server->sequence_number); | ||
| 121 | cifs_pdu->Signature.Sequence.Reserved = 0; | ||
| 122 | |||
| 123 | *pexpected_response_sequence_number = server->sequence_number++; | ||
| 124 | server->sequence_number++; | ||
| 125 | spin_unlock(&GlobalMid_Lock); | ||
| 126 | |||
| 127 | rc = cifs_calc_signature2(iov, n_vec, server->mac_signing_key, | ||
| 128 | smb_signature); | ||
| 129 | if(rc) | ||
| 130 | memset(cifs_pdu->Signature.SecuritySignature, 0, 8); | ||
| 131 | else | ||
| 132 | memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8); | ||
| 133 | |||
| 134 | return rc; | ||
| 135 | |||
| 136 | } | ||
| 137 | |||
| 85 | int cifs_verify_signature(struct smb_hdr * cifs_pdu, const char * mac_key, | 138 | int cifs_verify_signature(struct smb_hdr * cifs_pdu, const char * mac_key, |
| 86 | __u32 expected_sequence_number) | 139 | __u32 expected_sequence_number) |
| 87 | { | 140 | { |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index e10213b7541e..79eeccd0437f 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
| @@ -513,6 +513,17 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const char __user *buf, | |||
| 513 | return written; | 513 | return written; |
| 514 | } | 514 | } |
| 515 | 515 | ||
| 516 | static loff_t cifs_llseek(struct file *file, loff_t offset, int origin) | ||
| 517 | { | ||
| 518 | /* origin == SEEK_END => we must revalidate the cached file length */ | ||
| 519 | if (origin == 2) { | ||
| 520 | int retval = cifs_revalidate(file->f_dentry); | ||
| 521 | if (retval < 0) | ||
| 522 | return (loff_t)retval; | ||
| 523 | } | ||
| 524 | return remote_llseek(file, offset, origin); | ||
| 525 | } | ||
| 526 | |||
| 516 | static struct file_system_type cifs_fs_type = { | 527 | static struct file_system_type cifs_fs_type = { |
| 517 | .owner = THIS_MODULE, | 528 | .owner = THIS_MODULE, |
| 518 | .name = "cifs", | 529 | .name = "cifs", |
| @@ -586,6 +597,7 @@ struct file_operations cifs_file_ops = { | |||
| 586 | .flush = cifs_flush, | 597 | .flush = cifs_flush, |
| 587 | .mmap = cifs_file_mmap, | 598 | .mmap = cifs_file_mmap, |
| 588 | .sendfile = generic_file_sendfile, | 599 | .sendfile = generic_file_sendfile, |
| 600 | .llseek = cifs_llseek, | ||
| 589 | #ifdef CONFIG_CIFS_POSIX | 601 | #ifdef CONFIG_CIFS_POSIX |
| 590 | .ioctl = cifs_ioctl, | 602 | .ioctl = cifs_ioctl, |
| 591 | #endif /* CONFIG_CIFS_POSIX */ | 603 | #endif /* CONFIG_CIFS_POSIX */ |
| @@ -609,7 +621,7 @@ struct file_operations cifs_file_direct_ops = { | |||
| 609 | #ifdef CONFIG_CIFS_POSIX | 621 | #ifdef CONFIG_CIFS_POSIX |
| 610 | .ioctl = cifs_ioctl, | 622 | .ioctl = cifs_ioctl, |
| 611 | #endif /* CONFIG_CIFS_POSIX */ | 623 | #endif /* CONFIG_CIFS_POSIX */ |
| 612 | 624 | .llseek = cifs_llseek, | |
| 613 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 625 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
| 614 | .dir_notify = cifs_dir_notify, | 626 | .dir_notify = cifs_dir_notify, |
| 615 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | 627 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ |
| @@ -627,6 +639,7 @@ struct file_operations cifs_file_nobrl_ops = { | |||
| 627 | .flush = cifs_flush, | 639 | .flush = cifs_flush, |
| 628 | .mmap = cifs_file_mmap, | 640 | .mmap = cifs_file_mmap, |
| 629 | .sendfile = generic_file_sendfile, | 641 | .sendfile = generic_file_sendfile, |
| 642 | .llseek = cifs_llseek, | ||
| 630 | #ifdef CONFIG_CIFS_POSIX | 643 | #ifdef CONFIG_CIFS_POSIX |
| 631 | .ioctl = cifs_ioctl, | 644 | .ioctl = cifs_ioctl, |
| 632 | #endif /* CONFIG_CIFS_POSIX */ | 645 | #endif /* CONFIG_CIFS_POSIX */ |
| @@ -649,7 +662,7 @@ struct file_operations cifs_file_direct_nobrl_ops = { | |||
| 649 | #ifdef CONFIG_CIFS_POSIX | 662 | #ifdef CONFIG_CIFS_POSIX |
| 650 | .ioctl = cifs_ioctl, | 663 | .ioctl = cifs_ioctl, |
| 651 | #endif /* CONFIG_CIFS_POSIX */ | 664 | #endif /* CONFIG_CIFS_POSIX */ |
| 652 | 665 | .llseek = cifs_llseek, | |
| 653 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 666 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
| 654 | .dir_notify = cifs_dir_notify, | 667 | .dir_notify = cifs_dir_notify, |
| 655 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | 668 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ |
| @@ -733,7 +746,7 @@ cifs_init_request_bufs(void) | |||
| 733 | kmem_cache_destroy(cifs_req_cachep); | 746 | kmem_cache_destroy(cifs_req_cachep); |
| 734 | return -ENOMEM; | 747 | return -ENOMEM; |
| 735 | } | 748 | } |
| 736 | /* 256 (MAX_CIFS_HDR_SIZE bytes is enough for most SMB responses and | 749 | /* MAX_CIFS_SMALL_BUFFER_SIZE bytes is enough for most SMB responses and |
| 737 | almost all handle based requests (but not write response, nor is it | 750 | almost all handle based requests (but not write response, nor is it |
| 738 | sufficient for path based requests). A smaller size would have | 751 | sufficient for path based requests). A smaller size would have |
| 739 | been more efficient (compacting multiple slab items on one 4k page) | 752 | been more efficient (compacting multiple slab items on one 4k page) |
| @@ -742,7 +755,8 @@ cifs_init_request_bufs(void) | |||
| 742 | efficient to alloc 1 per page off the slab compared to 17K (5page) | 755 | efficient to alloc 1 per page off the slab compared to 17K (5page) |
| 743 | alloc of large cifs buffers even when page debugging is on */ | 756 | alloc of large cifs buffers even when page debugging is on */ |
| 744 | cifs_sm_req_cachep = kmem_cache_create("cifs_small_rq", | 757 | cifs_sm_req_cachep = kmem_cache_create("cifs_small_rq", |
| 745 | MAX_CIFS_HDR_SIZE, 0, SLAB_HWCACHE_ALIGN, NULL, NULL); | 758 | MAX_CIFS_SMALL_BUFFER_SIZE, 0, SLAB_HWCACHE_ALIGN, |
| 759 | NULL, NULL); | ||
| 746 | if (cifs_sm_req_cachep == NULL) { | 760 | if (cifs_sm_req_cachep == NULL) { |
| 747 | mempool_destroy(cifs_req_poolp); | 761 | mempool_destroy(cifs_req_poolp); |
| 748 | kmem_cache_destroy(cifs_req_cachep); | 762 | kmem_cache_destroy(cifs_req_cachep); |
| @@ -954,6 +968,12 @@ init_cifs(void) | |||
| 954 | atomic_set(&tconInfoReconnectCount, 0); | 968 | atomic_set(&tconInfoReconnectCount, 0); |
| 955 | 969 | ||
| 956 | atomic_set(&bufAllocCount, 0); | 970 | atomic_set(&bufAllocCount, 0); |
| 971 | atomic_set(&smBufAllocCount, 0); | ||
| 972 | #ifdef CONFIG_CIFS_STATS2 | ||
| 973 | atomic_set(&totBufAllocCount, 0); | ||
| 974 | atomic_set(&totSmBufAllocCount, 0); | ||
| 975 | #endif /* CONFIG_CIFS_STATS2 */ | ||
| 976 | |||
| 957 | atomic_set(&midCount, 0); | 977 | atomic_set(&midCount, 0); |
| 958 | GlobalCurrentXid = 0; | 978 | GlobalCurrentXid = 0; |
| 959 | GlobalTotalActiveXid = 0; | 979 | GlobalTotalActiveXid = 0; |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 9ec40e0e54fc..821a8eb22559 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
| @@ -99,5 +99,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); | |||
| 99 | extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); | 99 | extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); |
| 100 | extern int cifs_ioctl (struct inode * inode, struct file * filep, | 100 | extern int cifs_ioctl (struct inode * inode, struct file * filep, |
| 101 | unsigned int command, unsigned long arg); | 101 | unsigned int command, unsigned long arg); |
| 102 | #define CIFS_VERSION "1.39" | 102 | #define CIFS_VERSION "1.40" |
| 103 | #endif /* _CIFSFS_H */ | 103 | #endif /* _CIFSFS_H */ |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 1ba08f8c5bc4..7bed27601ce5 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
| @@ -233,6 +233,8 @@ struct cifsTconInfo { | |||
| 233 | atomic_t num_hardlinks; | 233 | atomic_t num_hardlinks; |
| 234 | atomic_t num_symlinks; | 234 | atomic_t num_symlinks; |
| 235 | atomic_t num_locks; | 235 | atomic_t num_locks; |
| 236 | atomic_t num_acl_get; | ||
| 237 | atomic_t num_acl_set; | ||
| 236 | #ifdef CONFIG_CIFS_STATS2 | 238 | #ifdef CONFIG_CIFS_STATS2 |
| 237 | unsigned long long time_writes; | 239 | unsigned long long time_writes; |
| 238 | unsigned long long time_reads; | 240 | unsigned long long time_reads; |
| @@ -285,6 +287,7 @@ struct cifs_search_info { | |||
| 285 | unsigned endOfSearch:1; | 287 | unsigned endOfSearch:1; |
| 286 | unsigned emptyDir:1; | 288 | unsigned emptyDir:1; |
| 287 | unsigned unicode:1; | 289 | unsigned unicode:1; |
| 290 | unsigned smallBuf:1; /* so we know which buf_release function to call */ | ||
| 288 | }; | 291 | }; |
| 289 | 292 | ||
| 290 | struct cifsFileInfo { | 293 | struct cifsFileInfo { |
| @@ -420,7 +423,12 @@ struct dir_notify_req { | |||
| 420 | #define MID_RESPONSE_RECEIVED 4 | 423 | #define MID_RESPONSE_RECEIVED 4 |
| 421 | #define MID_RETRY_NEEDED 8 /* session closed while this request out */ | 424 | #define MID_RETRY_NEEDED 8 /* session closed while this request out */ |
| 422 | #define MID_NO_RESP_NEEDED 0x10 | 425 | #define MID_NO_RESP_NEEDED 0x10 |
| 423 | #define MID_SMALL_BUFFER 0x20 /* 112 byte response buffer instead of 4K */ | 426 | |
| 427 | /* Types of response buffer returned from SendReceive2 */ | ||
| 428 | #define CIFS_NO_BUFFER 0 /* Response buffer not returned */ | ||
| 429 | #define CIFS_SMALL_BUFFER 1 | ||
| 430 | #define CIFS_LARGE_BUFFER 2 | ||
| 431 | #define CIFS_IOVEC 4 /* array of response buffers */ | ||
| 424 | 432 | ||
| 425 | /* | 433 | /* |
| 426 | ***************************************************************** | 434 | ***************************************************************** |
| @@ -505,8 +513,12 @@ GLOBAL_EXTERN atomic_t tcpSesReconnectCount; | |||
| 505 | GLOBAL_EXTERN atomic_t tconInfoReconnectCount; | 513 | GLOBAL_EXTERN atomic_t tconInfoReconnectCount; |
| 506 | 514 | ||
| 507 | /* Various Debug counters to remove someday (BB) */ | 515 | /* Various Debug counters to remove someday (BB) */ |
| 508 | GLOBAL_EXTERN atomic_t bufAllocCount; | 516 | GLOBAL_EXTERN atomic_t bufAllocCount; /* current number allocated */ |
| 509 | GLOBAL_EXTERN atomic_t smBufAllocCount; | 517 | #ifdef CONFIG_CIFS_STATS2 |
| 518 | GLOBAL_EXTERN atomic_t totBufAllocCount; /* total allocated over all time */ | ||
| 519 | GLOBAL_EXTERN atomic_t totSmBufAllocCount; | ||
| 520 | #endif | ||
| 521 | GLOBAL_EXTERN atomic_t smBufAllocCount; | ||
| 510 | GLOBAL_EXTERN atomic_t midCount; | 522 | GLOBAL_EXTERN atomic_t midCount; |
| 511 | 523 | ||
| 512 | /* Misc globals */ | 524 | /* Misc globals */ |
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 33e1859fd2f6..cc2471094ca5 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * fs/cifs/cifspdu.h | 2 | * fs/cifs/cifspdu.h |
| 3 | * | 3 | * |
| 4 | * Copyright (c) International Business Machines Corp., 2002 | 4 | * Copyright (c) International Business Machines Corp., 2002,2005 |
| 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 |
| @@ -80,7 +80,11 @@ | |||
| 80 | #define NT_TRANSACT_GET_USER_QUOTA 0x07 | 80 | #define NT_TRANSACT_GET_USER_QUOTA 0x07 |
| 81 | #define NT_TRANSACT_SET_USER_QUOTA 0x08 | 81 | #define NT_TRANSACT_SET_USER_QUOTA 0x08 |
| 82 | 82 | ||
| 83 | #define MAX_CIFS_HDR_SIZE 256 /* is future chained NTCreateXReadX bigger? */ | 83 | #define MAX_CIFS_SMALL_BUFFER_SIZE 448 /* big enough for most */ |
| 84 | /* future chained NTCreateXReadX bigger, but for time being NTCreateX biggest */ | ||
| 85 | /* among the requests (NTCreateX response is bigger with wct of 34) */ | ||
| 86 | #define MAX_CIFS_HDR_SIZE 0x58 /* 4 len + 32 hdr + (2*24 wct) + 2 bct + 2 pad */ | ||
| 87 | #define CIFS_SMALL_PATH 120 /* allows for (448-88)/3 */ | ||
| 84 | 88 | ||
| 85 | /* internal cifs vfs structures */ | 89 | /* internal cifs vfs structures */ |
| 86 | /***************************************************************** | 90 | /***************************************************************** |
| @@ -524,7 +528,7 @@ typedef union smb_com_session_setup_andx { | |||
| 524 | /* STRING PrimaryDomain */ | 528 | /* STRING PrimaryDomain */ |
| 525 | /* STRING NativeOS */ | 529 | /* STRING NativeOS */ |
| 526 | /* STRING NativeLanMan */ | 530 | /* STRING NativeLanMan */ |
| 527 | } __attribute__((packed)) old_req; /* pre-NTLM (LANMAN2.1) request format */ | 531 | } __attribute__((packed)) old_req; /* pre-NTLM (LANMAN2.1) req format */ |
| 528 | 532 | ||
| 529 | struct { /* default (NTLM) response format */ | 533 | struct { /* default (NTLM) response format */ |
| 530 | struct smb_hdr hdr; /* wct = 3 */ | 534 | struct smb_hdr hdr; /* wct = 3 */ |
| @@ -536,7 +540,7 @@ typedef union smb_com_session_setup_andx { | |||
| 536 | unsigned char NativeOS[1]; /* followed by */ | 540 | unsigned char NativeOS[1]; /* followed by */ |
| 537 | /* unsigned char * NativeLanMan; */ | 541 | /* unsigned char * NativeLanMan; */ |
| 538 | /* unsigned char * PrimaryDomain; */ | 542 | /* unsigned char * PrimaryDomain; */ |
| 539 | } __attribute__((packed)) old_resp; /* pre-NTLM (LANMAN2.1) response format */ | 543 | } __attribute__((packed)) old_resp; /* pre-NTLM (LANMAN2.1) response */ |
| 540 | } __attribute__((packed)) SESSION_SETUP_ANDX; | 544 | } __attribute__((packed)) SESSION_SETUP_ANDX; |
| 541 | 545 | ||
| 542 | #define CIFS_NETWORK_OPSYS "CIFS VFS Client for Linux" | 546 | #define CIFS_NETWORK_OPSYS "CIFS VFS Client for Linux" |
| @@ -1003,10 +1007,49 @@ typedef struct smb_com_setattr_rsp { | |||
| 1003 | 1007 | ||
| 1004 | /* empty wct response to setattr */ | 1008 | /* empty wct response to setattr */ |
| 1005 | 1009 | ||
| 1006 | /***************************************************/ | 1010 | /*******************************************************/ |
| 1007 | /* NT Transact structure defintions follow */ | 1011 | /* NT Transact structure defintions follow */ |
| 1008 | /* Currently only ioctl and notify are implemented */ | 1012 | /* Currently only ioctl, acl (get security descriptor) */ |
| 1009 | /***************************************************/ | 1013 | /* and notify are implemented */ |
| 1014 | /*******************************************************/ | ||
| 1015 | typedef struct smb_com_ntransact_req { | ||
| 1016 | struct smb_hdr hdr; /* wct >= 19 */ | ||
| 1017 | __u8 MaxSetupCount; | ||
| 1018 | __u16 Reserved; | ||
| 1019 | __le32 TotalParameterCount; | ||
| 1020 | __le32 TotalDataCount; | ||
| 1021 | __le32 MaxParameterCount; | ||
| 1022 | __le32 MaxDataCount; | ||
| 1023 | __le32 ParameterCount; | ||
| 1024 | __le32 ParameterOffset; | ||
| 1025 | __le32 DataCount; | ||
| 1026 | __le32 DataOffset; | ||
| 1027 | __u8 SetupCount; /* four setup words follow subcommand */ | ||
| 1028 | /* SNIA spec incorrectly included spurious pad here */ | ||
| 1029 | __le16 SubCommand; /* 2 = IOCTL/FSCTL */ | ||
| 1030 | /* SetupCount words follow then */ | ||
| 1031 | __le16 ByteCount; | ||
| 1032 | __u8 Pad[3]; | ||
| 1033 | __u8 Parms[0]; | ||
| 1034 | } __attribute__((packed)) NTRANSACT_REQ; | ||
| 1035 | |||
| 1036 | typedef struct smb_com_ntransact_rsp { | ||
| 1037 | struct smb_hdr hdr; /* wct = 18 */ | ||
| 1038 | __u8 Reserved[3]; | ||
| 1039 | __le32 TotalParameterCount; | ||
| 1040 | __le32 TotalDataCount; | ||
| 1041 | __le32 ParameterCount; | ||
| 1042 | __le32 ParameterOffset; | ||
| 1043 | __le32 ParameterDisplacement; | ||
| 1044 | __le32 DataCount; | ||
| 1045 | __le32 DataOffset; | ||
| 1046 | __le32 DataDisplacement; | ||
| 1047 | __u8 SetupCount; /* 0 */ | ||
| 1048 | __u16 ByteCount; | ||
| 1049 | /* __u8 Pad[3]; */ | ||
| 1050 | /* parms and data follow */ | ||
| 1051 | } __attribute__((packed)) NTRANSACT_RSP; | ||
| 1052 | |||
| 1010 | typedef struct smb_com_transaction_ioctl_req { | 1053 | typedef struct smb_com_transaction_ioctl_req { |
| 1011 | struct smb_hdr hdr; /* wct = 23 */ | 1054 | struct smb_hdr hdr; /* wct = 23 */ |
| 1012 | __u8 MaxSetupCount; | 1055 | __u8 MaxSetupCount; |
| @@ -1021,11 +1064,11 @@ typedef struct smb_com_transaction_ioctl_req { | |||
| 1021 | __le32 DataOffset; | 1064 | __le32 DataOffset; |
| 1022 | __u8 SetupCount; /* four setup words follow subcommand */ | 1065 | __u8 SetupCount; /* four setup words follow subcommand */ |
| 1023 | /* SNIA spec incorrectly included spurious pad here */ | 1066 | /* SNIA spec incorrectly included spurious pad here */ |
| 1024 | __le16 SubCommand;/* 2 = IOCTL/FSCTL */ | 1067 | __le16 SubCommand; /* 2 = IOCTL/FSCTL */ |
| 1025 | __le32 FunctionCode; | 1068 | __le32 FunctionCode; |
| 1026 | __u16 Fid; | 1069 | __u16 Fid; |
| 1027 | __u8 IsFsctl; /* 1 = File System Control, 0 = device control (IOCTL)*/ | 1070 | __u8 IsFsctl; /* 1 = File System Control 0 = device control (IOCTL) */ |
| 1028 | __u8 IsRootFlag; /* 1 = apply command to root of share (must be DFS share)*/ | 1071 | __u8 IsRootFlag; /* 1 = apply command to root of share (must be DFS) */ |
| 1029 | __le16 ByteCount; | 1072 | __le16 ByteCount; |
| 1030 | __u8 Pad[3]; | 1073 | __u8 Pad[3]; |
| 1031 | __u8 Data[1]; | 1074 | __u8 Data[1]; |
| @@ -1045,9 +1088,35 @@ typedef struct smb_com_transaction_ioctl_rsp { | |||
| 1045 | __u8 SetupCount; /* 1 */ | 1088 | __u8 SetupCount; /* 1 */ |
| 1046 | __le16 ReturnedDataLen; | 1089 | __le16 ReturnedDataLen; |
| 1047 | __u16 ByteCount; | 1090 | __u16 ByteCount; |
| 1048 | __u8 Pad[3]; | ||
| 1049 | } __attribute__((packed)) TRANSACT_IOCTL_RSP; | 1091 | } __attribute__((packed)) TRANSACT_IOCTL_RSP; |
| 1050 | 1092 | ||
| 1093 | #define CIFS_ACL_OWNER 1 | ||
| 1094 | #define CIFS_ACL_GROUP 2 | ||
| 1095 | #define CIFS_ACL_DACL 4 | ||
| 1096 | #define CIFS_ACL_SACL 8 | ||
| 1097 | |||
| 1098 | typedef struct smb_com_transaction_qsec_req { | ||
| 1099 | struct smb_hdr hdr; /* wct = 19 */ | ||
| 1100 | __u8 MaxSetupCount; | ||
| 1101 | __u16 Reserved; | ||
| 1102 | __le32 TotalParameterCount; | ||
| 1103 | __le32 TotalDataCount; | ||
| 1104 | __le32 MaxParameterCount; | ||
| 1105 | __le32 MaxDataCount; | ||
| 1106 | __le32 ParameterCount; | ||
| 1107 | __le32 ParameterOffset; | ||
| 1108 | __le32 DataCount; | ||
| 1109 | __le32 DataOffset; | ||
| 1110 | __u8 SetupCount; /* no setup words follow subcommand */ | ||
| 1111 | /* SNIA spec incorrectly included spurious pad here */ | ||
| 1112 | __le16 SubCommand; /* 6 = QUERY_SECURITY_DESC */ | ||
| 1113 | __le16 ByteCount; /* bcc = 3 + 8 */ | ||
| 1114 | __u8 Pad[3]; | ||
| 1115 | __u16 Fid; | ||
| 1116 | __u16 Reserved2; | ||
| 1117 | __le32 AclFlags; | ||
| 1118 | } __attribute__((packed)) QUERY_SEC_DESC_REQ; | ||
| 1119 | |||
| 1051 | typedef struct smb_com_transaction_change_notify_req { | 1120 | typedef struct smb_com_transaction_change_notify_req { |
| 1052 | struct smb_hdr hdr; /* wct = 23 */ | 1121 | struct smb_hdr hdr; /* wct = 23 */ |
| 1053 | __u8 MaxSetupCount; | 1122 | __u8 MaxSetupCount; |
| @@ -1068,10 +1137,12 @@ typedef struct smb_com_transaction_change_notify_req { | |||
| 1068 | __u8 WatchTree; /* 1 = Monitor subdirectories */ | 1137 | __u8 WatchTree; /* 1 = Monitor subdirectories */ |
| 1069 | __u8 Reserved2; | 1138 | __u8 Reserved2; |
| 1070 | __le16 ByteCount; | 1139 | __le16 ByteCount; |
| 1071 | /* __u8 Pad[3];*/ | 1140 | /* __u8 Pad[3];*/ |
| 1072 | /* __u8 Data[1];*/ | 1141 | /* __u8 Data[1];*/ |
| 1073 | } __attribute__((packed)) TRANSACT_CHANGE_NOTIFY_REQ; | 1142 | } __attribute__((packed)) TRANSACT_CHANGE_NOTIFY_REQ; |
| 1074 | 1143 | ||
| 1144 | /* BB eventually change to use generic ntransact rsp struct | ||
| 1145 | and validation routine */ | ||
| 1075 | typedef struct smb_com_transaction_change_notify_rsp { | 1146 | typedef struct smb_com_transaction_change_notify_rsp { |
| 1076 | struct smb_hdr hdr; /* wct = 18 */ | 1147 | struct smb_hdr hdr; /* wct = 18 */ |
| 1077 | __u8 Reserved[3]; | 1148 | __u8 Reserved[3]; |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 1b73f4f4c5ce..3c03aadaff0c 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
| @@ -48,8 +48,8 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *, | |||
| 48 | struct smb_hdr * /* out */ , | 48 | struct smb_hdr * /* out */ , |
| 49 | int * /* bytes returned */ , const int long_op); | 49 | int * /* bytes returned */ , const int long_op); |
| 50 | extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *, | 50 | extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *, |
| 51 | struct kvec *, int /* nvec */, | 51 | struct kvec *, int /* nvec to send */, |
| 52 | int * /* bytes returned */ , const int long_op); | 52 | int * /* type of buf returned */ , const int long_op); |
| 53 | extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid); | 53 | extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid); |
| 54 | extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length); | 54 | extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length); |
| 55 | extern int is_valid_oplock_break(struct smb_hdr *smb); | 55 | extern int is_valid_oplock_break(struct smb_hdr *smb); |
| @@ -93,11 +93,12 @@ extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, | |||
| 93 | const struct nls_table *); | 93 | const struct nls_table *); |
| 94 | 94 | ||
| 95 | extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, | 95 | extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, |
| 96 | const char *searchName, const struct nls_table *nls_codepage, | 96 | const char *searchName, const struct nls_table *nls_codepage, |
| 97 | __u16 *searchHandle, struct cifs_search_info * psrch_inf, int map, const char dirsep); | 97 | __u16 *searchHandle, struct cifs_search_info * psrch_inf, |
| 98 | int map, const char dirsep); | ||
| 98 | 99 | ||
| 99 | extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, | 100 | extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, |
| 100 | __u16 searchHandle, struct cifs_search_info * psrch_inf); | 101 | __u16 searchHandle, struct cifs_search_info * psrch_inf); |
| 101 | 102 | ||
| 102 | extern int CIFSFindClose(const int, struct cifsTconInfo *tcon, | 103 | extern int CIFSFindClose(const int, struct cifsTconInfo *tcon, |
| 103 | const __u16 search_handle); | 104 | const __u16 search_handle); |
| @@ -230,19 +231,18 @@ extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, | |||
| 230 | const int smb_file_id); | 231 | const int smb_file_id); |
| 231 | 232 | ||
| 232 | extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, | 233 | extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, |
| 233 | const int netfid, unsigned int count, | 234 | const int netfid, unsigned int count, |
| 234 | const __u64 lseek, unsigned int *nbytes, char **buf); | 235 | const __u64 lseek, unsigned int *nbytes, char **buf, |
| 236 | int * return_buf_type); | ||
| 235 | extern int CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, | 237 | extern int CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, |
| 236 | const int netfid, const unsigned int count, | 238 | const int netfid, const unsigned int count, |
| 237 | const __u64 lseek, unsigned int *nbytes, | 239 | const __u64 lseek, unsigned int *nbytes, |
| 238 | const char *buf, const char __user *ubuf, | 240 | const char *buf, const char __user *ubuf, |
| 239 | const int long_op); | 241 | const int long_op); |
| 240 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
| 241 | extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, | 242 | extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, |
| 242 | const int netfid, const unsigned int count, | 243 | const int netfid, const unsigned int count, |
| 243 | const __u64 offset, unsigned int *nbytes, | 244 | const __u64 offset, unsigned int *nbytes, |
| 244 | struct kvec *iov, const int nvec, const int long_op); | 245 | struct kvec *iov, const int nvec, const int long_op); |
| 245 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | ||
| 246 | extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, | 246 | extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, |
| 247 | const unsigned char *searchName, __u64 * inode_number, | 247 | const unsigned char *searchName, __u64 * inode_number, |
| 248 | const struct nls_table *nls_codepage, | 248 | const struct nls_table *nls_codepage, |
| @@ -269,6 +269,8 @@ extern void tconInfoFree(struct cifsTconInfo *); | |||
| 269 | extern int cifs_reconnect(struct TCP_Server_Info *server); | 269 | extern int cifs_reconnect(struct TCP_Server_Info *server); |
| 270 | 270 | ||
| 271 | extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *,__u32 *); | 271 | extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *,__u32 *); |
| 272 | extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, | ||
| 273 | __u32 *); | ||
| 272 | extern int cifs_verify_signature(struct smb_hdr *, const char * mac_key, | 274 | extern int cifs_verify_signature(struct smb_hdr *, const char * mac_key, |
| 273 | __u32 expected_sequence_number); | 275 | __u32 expected_sequence_number); |
| 274 | extern int cifs_calculate_mac_key(char * key,const char * rn,const char * pass); | 276 | extern int cifs_calculate_mac_key(char * key,const char * rn,const char * pass); |
| @@ -297,6 +299,9 @@ extern int CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, | |||
| 297 | const char *fileName, const char * ea_name, | 299 | const char *fileName, const char * ea_name, |
| 298 | const void * ea_value, const __u16 ea_value_len, | 300 | const void * ea_value, const __u16 ea_value_len, |
| 299 | const struct nls_table *nls_codepage, int remap_special_chars); | 301 | const struct nls_table *nls_codepage, int remap_special_chars); |
| 302 | extern int CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, | ||
| 303 | __u16 fid, char *acl_inf, const int buflen, | ||
| 304 | const int acl_type /* ACCESS vs. DEFAULT */); | ||
| 300 | extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon, | 305 | extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon, |
| 301 | const unsigned char *searchName, | 306 | const unsigned char *searchName, |
| 302 | char *acl_inf, const int buflen,const int acl_type, | 307 | char *acl_inf, const int buflen,const int acl_type, |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 6867e556d37e..217323b0c896 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | #include "cifsproto.h" | 37 | #include "cifsproto.h" |
| 38 | #include "cifs_unicode.h" | 38 | #include "cifs_unicode.h" |
| 39 | #include "cifs_debug.h" | 39 | #include "cifs_debug.h" |
| 40 | #include "cifsacl.h" | ||
| 40 | 41 | ||
| 41 | #ifdef CONFIG_CIFS_POSIX | 42 | #ifdef CONFIG_CIFS_POSIX |
| 42 | static struct { | 43 | static struct { |
| @@ -372,8 +373,10 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
| 372 | rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, | 373 | rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, |
| 373 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | 374 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); |
| 374 | if (rc == 0) { | 375 | if (rc == 0) { |
| 375 | server->secMode = pSMBr->SecurityMode; | 376 | server->secMode = pSMBr->SecurityMode; |
| 376 | server->secType = NTLM; /* BB override default for | 377 | if((server->secMode & SECMODE_USER) == 0) |
| 378 | cFYI(1,("share mode security")); | ||
| 379 | server->secType = NTLM; /* BB override default for | ||
| 377 | NTLMv2 or kerberos v5 */ | 380 | NTLMv2 or kerberos v5 */ |
| 378 | /* one byte - no need to convert this or EncryptionKeyLen | 381 | /* one byte - no need to convert this or EncryptionKeyLen |
| 379 | from little endian */ | 382 | from little endian */ |
| @@ -383,7 +386,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
| 383 | min(le32_to_cpu(pSMBr->MaxBufferSize), | 386 | min(le32_to_cpu(pSMBr->MaxBufferSize), |
| 384 | (__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); | 387 | (__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); |
| 385 | server->maxRw = le32_to_cpu(pSMBr->MaxRawSize); | 388 | server->maxRw = le32_to_cpu(pSMBr->MaxRawSize); |
| 386 | cFYI(0, ("Max buf = %d ", ses->server->maxBuf)); | 389 | cFYI(0, ("Max buf = %d", ses->server->maxBuf)); |
| 387 | GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey); | 390 | GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey); |
| 388 | server->capabilities = le32_to_cpu(pSMBr->Capabilities); | 391 | server->capabilities = le32_to_cpu(pSMBr->Capabilities); |
| 389 | server->timeZone = le16_to_cpu(pSMBr->ServerTimeZone); | 392 | server->timeZone = le16_to_cpu(pSMBr->ServerTimeZone); |
| @@ -411,8 +414,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
| 411 | (server->server_GUID, | 414 | (server->server_GUID, |
| 412 | pSMBr->u.extended_response. | 415 | pSMBr->u.extended_response. |
| 413 | GUID, 16) != 0) { | 416 | GUID, 16) != 0) { |
| 414 | cFYI(1, | 417 | cFYI(1, ("server UID changed")); |
| 415 | ("UID of server does not match previous connection to same ip address")); | ||
| 416 | memcpy(server-> | 418 | memcpy(server-> |
| 417 | server_GUID, | 419 | server_GUID, |
| 418 | pSMBr->u. | 420 | pSMBr->u. |
| @@ -958,21 +960,19 @@ openRetry: | |||
| 958 | return rc; | 960 | return rc; |
| 959 | } | 961 | } |
| 960 | 962 | ||
| 961 | /* If no buffer passed in, then caller wants to do the copy | ||
| 962 | as in the case of readpages so the SMB buffer must be | ||
| 963 | freed by the caller */ | ||
| 964 | |||
| 965 | int | 963 | int |
| 966 | CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, | 964 | CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, |
| 967 | const int netfid, const unsigned int count, | 965 | const int netfid, const unsigned int count, |
| 968 | const __u64 lseek, unsigned int *nbytes, char **buf) | 966 | const __u64 lseek, unsigned int *nbytes, char **buf, |
| 967 | int * pbuf_type) | ||
| 969 | { | 968 | { |
| 970 | int rc = -EACCES; | 969 | int rc = -EACCES; |
| 971 | READ_REQ *pSMB = NULL; | 970 | READ_REQ *pSMB = NULL; |
| 972 | READ_RSP *pSMBr = NULL; | 971 | READ_RSP *pSMBr = NULL; |
| 973 | char *pReadData = NULL; | 972 | char *pReadData = NULL; |
| 974 | int bytes_returned; | ||
| 975 | int wct; | 973 | int wct; |
| 974 | int resp_buf_type = 0; | ||
| 975 | struct kvec iov[1]; | ||
| 976 | 976 | ||
| 977 | cFYI(1,("Reading %d bytes on fid %d",count,netfid)); | 977 | cFYI(1,("Reading %d bytes on fid %d",count,netfid)); |
| 978 | if(tcon->ses->capabilities & CAP_LARGE_FILES) | 978 | if(tcon->ses->capabilities & CAP_LARGE_FILES) |
| @@ -981,8 +981,7 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, | |||
| 981 | wct = 10; /* old style read */ | 981 | wct = 10; /* old style read */ |
| 982 | 982 | ||
| 983 | *nbytes = 0; | 983 | *nbytes = 0; |
| 984 | rc = smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB, | 984 | rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB); |
| 985 | (void **) &pSMBr); | ||
| 986 | if (rc) | 985 | if (rc) |
| 987 | return rc; | 986 | return rc; |
| 988 | 987 | ||
| @@ -990,13 +989,13 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, | |||
| 990 | if (tcon->ses->server == NULL) | 989 | if (tcon->ses->server == NULL) |
| 991 | return -ECONNABORTED; | 990 | return -ECONNABORTED; |
| 992 | 991 | ||
| 993 | pSMB->AndXCommand = 0xFF; /* none */ | 992 | pSMB->AndXCommand = 0xFF; /* none */ |
| 994 | pSMB->Fid = netfid; | 993 | pSMB->Fid = netfid; |
| 995 | pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF); | 994 | pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF); |
| 996 | if(wct == 12) | 995 | if(wct == 12) |
| 997 | pSMB->OffsetHigh = cpu_to_le32(lseek >> 32); | 996 | pSMB->OffsetHigh = cpu_to_le32(lseek >> 32); |
| 998 | else if((lseek >> 32) > 0) /* can not handle this big offset for old */ | 997 | else if((lseek >> 32) > 0) /* can not handle this big offset for old */ |
| 999 | return -EIO; | 998 | return -EIO; |
| 1000 | 999 | ||
| 1001 | pSMB->Remaining = 0; | 1000 | pSMB->Remaining = 0; |
| 1002 | pSMB->MaxCount = cpu_to_le16(count & 0xFFFF); | 1001 | pSMB->MaxCount = cpu_to_le16(count & 0xFFFF); |
| @@ -1005,14 +1004,18 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, | |||
| 1005 | pSMB->ByteCount = 0; /* no need to do le conversion since 0 */ | 1004 | pSMB->ByteCount = 0; /* no need to do le conversion since 0 */ |
| 1006 | else { | 1005 | else { |
| 1007 | /* old style read */ | 1006 | /* old style read */ |
| 1008 | struct smb_com_readx_req * pSMBW = | 1007 | struct smb_com_readx_req * pSMBW = |
| 1009 | (struct smb_com_readx_req *)pSMB; | 1008 | (struct smb_com_readx_req *)pSMB; |
| 1010 | pSMBW->ByteCount = 0; | 1009 | pSMBW->ByteCount = 0; |
| 1011 | } | 1010 | } |
| 1012 | 1011 | ||
| 1013 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, | 1012 | iov[0].iov_base = (char *)pSMB; |
| 1014 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | 1013 | iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; |
| 1014 | rc = SendReceive2(xid, tcon->ses, iov, | ||
| 1015 | 1 /* num iovecs */, | ||
| 1016 | &resp_buf_type, 0); | ||
| 1015 | cifs_stats_inc(&tcon->num_reads); | 1017 | cifs_stats_inc(&tcon->num_reads); |
| 1018 | pSMBr = (READ_RSP *)iov[0].iov_base; | ||
| 1016 | if (rc) { | 1019 | if (rc) { |
| 1017 | cERROR(1, ("Send error in read = %d", rc)); | 1020 | cERROR(1, ("Send error in read = %d", rc)); |
| 1018 | } else { | 1021 | } else { |
| @@ -1022,33 +1025,43 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, | |||
| 1022 | *nbytes = data_length; | 1025 | *nbytes = data_length; |
| 1023 | 1026 | ||
| 1024 | /*check that DataLength would not go beyond end of SMB */ | 1027 | /*check that DataLength would not go beyond end of SMB */ |
| 1025 | if ((data_length > CIFSMaxBufSize) | 1028 | if ((data_length > CIFSMaxBufSize) |
| 1026 | || (data_length > count)) { | 1029 | || (data_length > count)) { |
| 1027 | cFYI(1,("bad length %d for count %d",data_length,count)); | 1030 | cFYI(1,("bad length %d for count %d",data_length,count)); |
| 1028 | rc = -EIO; | 1031 | rc = -EIO; |
| 1029 | *nbytes = 0; | 1032 | *nbytes = 0; |
| 1030 | } else { | 1033 | } else { |
| 1031 | pReadData = | 1034 | pReadData = (char *) (&pSMBr->hdr.Protocol) + |
| 1032 | (char *) (&pSMBr->hdr.Protocol) + | ||
| 1033 | le16_to_cpu(pSMBr->DataOffset); | 1035 | le16_to_cpu(pSMBr->DataOffset); |
| 1034 | /* if(rc = copy_to_user(buf, pReadData, data_length)) { | 1036 | /* if(rc = copy_to_user(buf, pReadData, data_length)) { |
| 1035 | cERROR(1,("Faulting on read rc = %d",rc)); | 1037 | cERROR(1,("Faulting on read rc = %d",rc)); |
| 1036 | rc = -EFAULT; | 1038 | rc = -EFAULT; |
| 1037 | }*/ /* can not use copy_to_user when using page cache*/ | 1039 | }*/ /* can not use copy_to_user when using page cache*/ |
| 1038 | if(*buf) | 1040 | if(*buf) |
| 1039 | memcpy(*buf,pReadData,data_length); | 1041 | memcpy(*buf,pReadData,data_length); |
| 1040 | } | 1042 | } |
| 1041 | } | 1043 | } |
| 1042 | if(*buf) | ||
| 1043 | cifs_buf_release(pSMB); | ||
| 1044 | else | ||
| 1045 | *buf = (char *)pSMB; | ||
| 1046 | 1044 | ||
| 1047 | /* Note: On -EAGAIN error only caller can retry on handle based calls | 1045 | cifs_small_buf_release(pSMB); |
| 1046 | if(*buf) { | ||
| 1047 | if(resp_buf_type == CIFS_SMALL_BUFFER) | ||
| 1048 | cifs_small_buf_release(iov[0].iov_base); | ||
| 1049 | else if(resp_buf_type == CIFS_LARGE_BUFFER) | ||
| 1050 | cifs_buf_release(iov[0].iov_base); | ||
| 1051 | } else /* return buffer to caller to free */ /* BB FIXME how do we tell caller if it is not a large buffer */ { | ||
| 1052 | *buf = iov[0].iov_base; | ||
| 1053 | if(resp_buf_type == CIFS_SMALL_BUFFER) | ||
| 1054 | *pbuf_type = CIFS_SMALL_BUFFER; | ||
| 1055 | else if(resp_buf_type == CIFS_LARGE_BUFFER) | ||
| 1056 | *pbuf_type = CIFS_LARGE_BUFFER; | ||
| 1057 | } | ||
| 1058 | |||
| 1059 | /* Note: On -EAGAIN error only caller can retry on handle based calls | ||
| 1048 | since file handle passed in no longer valid */ | 1060 | since file handle passed in no longer valid */ |
| 1049 | return rc; | 1061 | return rc; |
| 1050 | } | 1062 | } |
| 1051 | 1063 | ||
| 1064 | |||
| 1052 | int | 1065 | int |
| 1053 | CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, | 1066 | CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, |
| 1054 | const int netfid, const unsigned int count, | 1067 | const int netfid, const unsigned int count, |
| @@ -1155,7 +1168,6 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, | |||
| 1155 | return rc; | 1168 | return rc; |
| 1156 | } | 1169 | } |
| 1157 | 1170 | ||
| 1158 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
| 1159 | int | 1171 | int |
| 1160 | CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, | 1172 | CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, |
| 1161 | const int netfid, const unsigned int count, | 1173 | const int netfid, const unsigned int count, |
| @@ -1164,10 +1176,10 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, | |||
| 1164 | { | 1176 | { |
| 1165 | int rc = -EACCES; | 1177 | int rc = -EACCES; |
| 1166 | WRITE_REQ *pSMB = NULL; | 1178 | WRITE_REQ *pSMB = NULL; |
| 1167 | int bytes_returned, wct; | 1179 | int wct; |
| 1168 | int smb_hdr_len; | 1180 | int smb_hdr_len; |
| 1181 | int resp_buf_type = 0; | ||
| 1169 | 1182 | ||
| 1170 | /* BB removeme BB */ | ||
| 1171 | cFYI(1,("write2 at %lld %d bytes", (long long)offset, count)); | 1183 | cFYI(1,("write2 at %lld %d bytes", (long long)offset, count)); |
| 1172 | 1184 | ||
| 1173 | if(tcon->ses->capabilities & CAP_LARGE_FILES) | 1185 | if(tcon->ses->capabilities & CAP_LARGE_FILES) |
| @@ -1210,22 +1222,34 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, | |||
| 1210 | pSMBW->ByteCount = cpu_to_le16(count + 5); | 1222 | pSMBW->ByteCount = cpu_to_le16(count + 5); |
| 1211 | } | 1223 | } |
| 1212 | iov[0].iov_base = pSMB; | 1224 | iov[0].iov_base = pSMB; |
| 1213 | iov[0].iov_len = smb_hdr_len + 4; | 1225 | if(wct == 14) |
| 1226 | iov[0].iov_len = smb_hdr_len + 4; | ||
| 1227 | else /* wct == 12 pad bigger by four bytes */ | ||
| 1228 | iov[0].iov_len = smb_hdr_len + 8; | ||
| 1229 | |||
| 1214 | 1230 | ||
| 1215 | rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &bytes_returned, | 1231 | rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, |
| 1216 | long_op); | 1232 | long_op); |
| 1217 | cifs_stats_inc(&tcon->num_writes); | 1233 | cifs_stats_inc(&tcon->num_writes); |
| 1218 | if (rc) { | 1234 | if (rc) { |
| 1219 | cFYI(1, ("Send error Write2 = %d", rc)); | 1235 | cFYI(1, ("Send error Write2 = %d", rc)); |
| 1220 | *nbytes = 0; | 1236 | *nbytes = 0; |
| 1237 | } else if(resp_buf_type == 0) { | ||
| 1238 | /* presumably this can not happen, but best to be safe */ | ||
| 1239 | rc = -EIO; | ||
| 1240 | *nbytes = 0; | ||
| 1221 | } else { | 1241 | } else { |
| 1222 | WRITE_RSP * pSMBr = (WRITE_RSP *)pSMB; | 1242 | WRITE_RSP * pSMBr = (WRITE_RSP *)iov[0].iov_base; |
| 1223 | *nbytes = le16_to_cpu(pSMBr->CountHigh); | 1243 | *nbytes = le16_to_cpu(pSMBr->CountHigh); |
| 1224 | *nbytes = (*nbytes) << 16; | 1244 | *nbytes = (*nbytes) << 16; |
| 1225 | *nbytes += le16_to_cpu(pSMBr->Count); | 1245 | *nbytes += le16_to_cpu(pSMBr->Count); |
| 1226 | } | 1246 | } |
| 1227 | 1247 | ||
| 1228 | cifs_small_buf_release(pSMB); | 1248 | cifs_small_buf_release(pSMB); |
| 1249 | if(resp_buf_type == CIFS_SMALL_BUFFER) | ||
| 1250 | cifs_small_buf_release(iov[0].iov_base); | ||
| 1251 | else if(resp_buf_type == CIFS_LARGE_BUFFER) | ||
| 1252 | cifs_buf_release(iov[0].iov_base); | ||
| 1229 | 1253 | ||
| 1230 | /* Note: On -EAGAIN error only caller can retry on handle based calls | 1254 | /* Note: On -EAGAIN error only caller can retry on handle based calls |
| 1231 | since file handle passed in no longer valid */ | 1255 | since file handle passed in no longer valid */ |
| @@ -1234,8 +1258,6 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, | |||
| 1234 | } | 1258 | } |
| 1235 | 1259 | ||
| 1236 | 1260 | ||
| 1237 | #endif /* CIFS_EXPERIMENTAL */ | ||
| 1238 | |||
| 1239 | int | 1261 | int |
| 1240 | CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, | 1262 | CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, |
| 1241 | const __u16 smb_file_id, const __u64 len, | 1263 | const __u16 smb_file_id, const __u64 len, |
| @@ -1906,6 +1928,90 @@ querySymLinkRetry: | |||
| 1906 | return rc; | 1928 | return rc; |
| 1907 | } | 1929 | } |
| 1908 | 1930 | ||
| 1931 | /* Initialize NT TRANSACT SMB into small smb request buffer. | ||
| 1932 | This assumes that all NT TRANSACTS that we init here have | ||
| 1933 | total parm and data under about 400 bytes (to fit in small cifs | ||
| 1934 | buffer size), which is the case so far, it easily fits. NB: | ||
| 1935 | Setup words themselves and ByteCount | ||
| 1936 | MaxSetupCount (size of returned setup area) and | ||
| 1937 | MaxParameterCount (returned parms size) must be set by caller */ | ||
| 1938 | static int | ||
| 1939 | smb_init_ntransact(const __u16 sub_command, const int setup_count, | ||
| 1940 | const int parm_len, struct cifsTconInfo *tcon, | ||
| 1941 | void ** ret_buf) | ||
| 1942 | { | ||
| 1943 | int rc; | ||
| 1944 | __u32 temp_offset; | ||
| 1945 | struct smb_com_ntransact_req * pSMB; | ||
| 1946 | |||
| 1947 | rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon, | ||
| 1948 | (void **)&pSMB); | ||
| 1949 | if (rc) | ||
| 1950 | return rc; | ||
| 1951 | *ret_buf = (void *)pSMB; | ||
| 1952 | pSMB->Reserved = 0; | ||
| 1953 | pSMB->TotalParameterCount = cpu_to_le32(parm_len); | ||
| 1954 | pSMB->TotalDataCount = 0; | ||
| 1955 | pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf - | ||
| 1956 | MAX_CIFS_HDR_SIZE) & 0xFFFFFF00); | ||
| 1957 | pSMB->ParameterCount = pSMB->TotalParameterCount; | ||
| 1958 | pSMB->DataCount = pSMB->TotalDataCount; | ||
| 1959 | temp_offset = offsetof(struct smb_com_ntransact_req, Parms) + | ||
| 1960 | (setup_count * 2) - 4 /* for rfc1001 length itself */; | ||
| 1961 | pSMB->ParameterOffset = cpu_to_le32(temp_offset); | ||
| 1962 | pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len); | ||
| 1963 | pSMB->SetupCount = setup_count; /* no need to le convert byte fields */ | ||
| 1964 | pSMB->SubCommand = cpu_to_le16(sub_command); | ||
| 1965 | return 0; | ||
| 1966 | } | ||
| 1967 | |||
| 1968 | static int | ||
| 1969 | validate_ntransact(char * buf, char ** ppparm, char ** ppdata, | ||
| 1970 | int * pdatalen, int * pparmlen) | ||
| 1971 | { | ||
| 1972 | char * end_of_smb; | ||
| 1973 | __u32 data_count, data_offset, parm_count, parm_offset; | ||
| 1974 | struct smb_com_ntransact_rsp * pSMBr; | ||
| 1975 | |||
| 1976 | if(buf == NULL) | ||
| 1977 | return -EINVAL; | ||
| 1978 | |||
| 1979 | pSMBr = (struct smb_com_ntransact_rsp *)buf; | ||
| 1980 | |||
| 1981 | /* ByteCount was converted from little endian in SendReceive */ | ||
| 1982 | end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount + | ||
| 1983 | (char *)&pSMBr->ByteCount; | ||
| 1984 | |||
| 1985 | |||
| 1986 | data_offset = le32_to_cpu(pSMBr->DataOffset); | ||
| 1987 | data_count = le32_to_cpu(pSMBr->DataCount); | ||
| 1988 | parm_offset = le32_to_cpu(pSMBr->ParameterOffset); | ||
| 1989 | parm_count = le32_to_cpu(pSMBr->ParameterCount); | ||
| 1990 | |||
| 1991 | *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset; | ||
| 1992 | *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset; | ||
| 1993 | |||
| 1994 | /* should we also check that parm and data areas do not overlap? */ | ||
| 1995 | if(*ppparm > end_of_smb) { | ||
| 1996 | cFYI(1,("parms start after end of smb")); | ||
| 1997 | return -EINVAL; | ||
| 1998 | } else if(parm_count + *ppparm > end_of_smb) { | ||
| 1999 | cFYI(1,("parm end after end of smb")); | ||
| 2000 | return -EINVAL; | ||
| 2001 | } else if(*ppdata > end_of_smb) { | ||
| 2002 | cFYI(1,("data starts after end of smb")); | ||
| 2003 | return -EINVAL; | ||
| 2004 | } else if(data_count + *ppdata > end_of_smb) { | ||
| 2005 | cFYI(1,("data %p + count %d (%p) ends after end of smb %p start %p", | ||
| 2006 | *ppdata, data_count, (data_count + *ppdata), end_of_smb, pSMBr)); /* BB FIXME */ | ||
| 2007 | return -EINVAL; | ||
| 2008 | } else if(parm_count + data_count > pSMBr->ByteCount) { | ||
| 2009 | cFYI(1,("parm count and data count larger than SMB")); | ||
| 2010 | return -EINVAL; | ||
| 2011 | } | ||
| 2012 | return 0; | ||
| 2013 | } | ||
| 2014 | |||
| 1909 | int | 2015 | int |
| 1910 | CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, | 2016 | CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, |
| 1911 | const unsigned char *searchName, | 2017 | const unsigned char *searchName, |
| @@ -1928,7 +2034,8 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, | |||
| 1928 | pSMB->TotalDataCount = 0; | 2034 | pSMB->TotalDataCount = 0; |
| 1929 | pSMB->MaxParameterCount = cpu_to_le32(2); | 2035 | pSMB->MaxParameterCount = cpu_to_le32(2); |
| 1930 | /* BB find exact data count max from sess structure BB */ | 2036 | /* BB find exact data count max from sess structure BB */ |
| 1931 | pSMB->MaxDataCount = cpu_to_le32(4000); | 2037 | pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf - |
| 2038 | MAX_CIFS_HDR_SIZE) & 0xFFFFFF00); | ||
| 1932 | pSMB->MaxSetupCount = 4; | 2039 | pSMB->MaxSetupCount = 4; |
| 1933 | pSMB->Reserved = 0; | 2040 | pSMB->Reserved = 0; |
| 1934 | pSMB->ParameterOffset = 0; | 2041 | pSMB->ParameterOffset = 0; |
| @@ -1955,7 +2062,9 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, | |||
| 1955 | rc = -EIO; /* bad smb */ | 2062 | rc = -EIO; /* bad smb */ |
| 1956 | else { | 2063 | else { |
| 1957 | if(data_count && (data_count < 2048)) { | 2064 | if(data_count && (data_count < 2048)) { |
| 1958 | char * end_of_smb = pSMBr->ByteCount + (char *)&pSMBr->ByteCount; | 2065 | char * end_of_smb = 2 /* sizeof byte count */ + |
| 2066 | pSMBr->ByteCount + | ||
| 2067 | (char *)&pSMBr->ByteCount; | ||
| 1959 | 2068 | ||
| 1960 | struct reparse_data * reparse_buf = (struct reparse_data *) | 2069 | struct reparse_data * reparse_buf = (struct reparse_data *) |
| 1961 | ((char *)&pSMBr->hdr.Protocol + data_offset); | 2070 | ((char *)&pSMBr->hdr.Protocol + data_offset); |
| @@ -2199,6 +2308,7 @@ queryAclRetry: | |||
| 2199 | 2308 | ||
| 2200 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, | 2309 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, |
| 2201 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | 2310 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); |
| 2311 | cifs_stats_inc(&tcon->num_acl_get); | ||
| 2202 | if (rc) { | 2312 | if (rc) { |
| 2203 | cFYI(1, ("Send error in Query POSIX ACL = %d", rc)); | 2313 | cFYI(1, ("Send error in Query POSIX ACL = %d", rc)); |
| 2204 | } else { | 2314 | } else { |
| @@ -2386,6 +2496,92 @@ GetExtAttrOut: | |||
| 2386 | 2496 | ||
| 2387 | #endif /* CONFIG_POSIX */ | 2497 | #endif /* CONFIG_POSIX */ |
| 2388 | 2498 | ||
| 2499 | |||
| 2500 | /* security id for everyone */ | ||
| 2501 | const struct cifs_sid sid_everyone = {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}}; | ||
| 2502 | /* group users */ | ||
| 2503 | const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}}; | ||
| 2504 | |||
| 2505 | /* Convert CIFS ACL to POSIX form */ | ||
| 2506 | static int parse_sec_desc(struct cifs_sid * psec_desc, int acl_len) | ||
| 2507 | { | ||
| 2508 | return 0; | ||
| 2509 | } | ||
| 2510 | |||
| 2511 | /* Get Security Descriptor (by handle) from remote server for a file or dir */ | ||
| 2512 | int | ||
| 2513 | CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, | ||
| 2514 | /* BB fix up return info */ char *acl_inf, const int buflen, | ||
| 2515 | const int acl_type /* ACCESS/DEFAULT not sure implication */) | ||
| 2516 | { | ||
| 2517 | int rc = 0; | ||
| 2518 | int buf_type = 0; | ||
| 2519 | QUERY_SEC_DESC_REQ * pSMB; | ||
| 2520 | struct kvec iov[1]; | ||
| 2521 | |||
| 2522 | cFYI(1, ("GetCifsACL")); | ||
| 2523 | |||
| 2524 | rc = smb_init_ntransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0, | ||
| 2525 | 8 /* parm len */, tcon, (void **) &pSMB); | ||
| 2526 | if (rc) | ||
| 2527 | return rc; | ||
| 2528 | |||
| 2529 | pSMB->MaxParameterCount = cpu_to_le32(4); | ||
| 2530 | /* BB TEST with big acls that might need to be e.g. larger than 16K */ | ||
| 2531 | pSMB->MaxSetupCount = 0; | ||
| 2532 | pSMB->Fid = fid; /* file handle always le */ | ||
| 2533 | pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP | | ||
| 2534 | CIFS_ACL_DACL); | ||
| 2535 | pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */ | ||
| 2536 | pSMB->hdr.smb_buf_length += 11; | ||
| 2537 | iov[0].iov_base = (char *)pSMB; | ||
| 2538 | iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; | ||
| 2539 | |||
| 2540 | rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, 0); | ||
| 2541 | cifs_stats_inc(&tcon->num_acl_get); | ||
| 2542 | if (rc) { | ||
| 2543 | cFYI(1, ("Send error in QuerySecDesc = %d", rc)); | ||
| 2544 | } else { /* decode response */ | ||
| 2545 | struct cifs_sid * psec_desc; | ||
| 2546 | __le32 * parm; | ||
| 2547 | int parm_len; | ||
| 2548 | int data_len; | ||
| 2549 | int acl_len; | ||
| 2550 | struct smb_com_ntransact_rsp * pSMBr; | ||
| 2551 | |||
| 2552 | /* validate_nttransact */ | ||
| 2553 | rc = validate_ntransact(iov[0].iov_base, (char **)&parm, | ||
| 2554 | (char **)&psec_desc, | ||
| 2555 | &parm_len, &data_len); | ||
| 2556 | |||
| 2557 | if(rc) | ||
| 2558 | goto qsec_out; | ||
| 2559 | pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base; | ||
| 2560 | |||
| 2561 | cERROR(1,("smb %p parm %p data %p",pSMBr,parm,psec_desc)); /* BB removeme BB */ | ||
| 2562 | |||
| 2563 | if (le32_to_cpu(pSMBr->ParameterCount) != 4) { | ||
| 2564 | rc = -EIO; /* bad smb */ | ||
| 2565 | goto qsec_out; | ||
| 2566 | } | ||
| 2567 | |||
| 2568 | /* BB check that data area is minimum length and as big as acl_len */ | ||
| 2569 | |||
| 2570 | acl_len = le32_to_cpu(*(__le32 *)parm); | ||
| 2571 | /* BB check if(acl_len > bufsize) */ | ||
| 2572 | |||
| 2573 | parse_sec_desc(psec_desc, acl_len); | ||
| 2574 | } | ||
| 2575 | qsec_out: | ||
| 2576 | if(buf_type == CIFS_SMALL_BUFFER) | ||
| 2577 | cifs_small_buf_release(iov[0].iov_base); | ||
| 2578 | else if(buf_type == CIFS_LARGE_BUFFER) | ||
| 2579 | cifs_buf_release(iov[0].iov_base); | ||
| 2580 | cifs_small_buf_release(pSMB); | ||
| 2581 | return rc; | ||
| 2582 | } | ||
| 2583 | |||
| 2584 | |||
| 2389 | /* Legacy Query Path Information call for lookup to old servers such | 2585 | /* Legacy Query Path Information call for lookup to old servers such |
| 2390 | as Win9x/WinME */ | 2586 | as Win9x/WinME */ |
| 2391 | int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, | 2587 | int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, |
| @@ -4284,7 +4480,7 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, | |||
| 4284 | { | 4480 | { |
| 4285 | int rc = 0; | 4481 | int rc = 0; |
| 4286 | struct smb_com_transaction_change_notify_req * pSMB = NULL; | 4482 | struct smb_com_transaction_change_notify_req * pSMB = NULL; |
| 4287 | struct smb_com_transaction_change_notify_rsp * pSMBr = NULL; | 4483 | struct smb_com_ntransaction_change_notify_rsp * pSMBr = NULL; |
| 4288 | struct dir_notify_req *dnotify_req; | 4484 | struct dir_notify_req *dnotify_req; |
| 4289 | int bytes_returned; | 4485 | int bytes_returned; |
| 4290 | 4486 | ||
| @@ -4299,6 +4495,10 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, | |||
| 4299 | pSMB->MaxParameterCount = cpu_to_le32(2); | 4495 | pSMB->MaxParameterCount = cpu_to_le32(2); |
| 4300 | /* BB find exact data count max from sess structure BB */ | 4496 | /* BB find exact data count max from sess structure BB */ |
| 4301 | pSMB->MaxDataCount = 0; /* same in little endian or be */ | 4497 | pSMB->MaxDataCount = 0; /* same in little endian or be */ |
| 4498 | /* BB VERIFY verify which is correct for above BB */ | ||
| 4499 | pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf - | ||
| 4500 | MAX_CIFS_HDR_SIZE) & 0xFFFFFF00); | ||
| 4501 | |||
| 4302 | pSMB->MaxSetupCount = 4; | 4502 | pSMB->MaxSetupCount = 4; |
| 4303 | pSMB->Reserved = 0; | 4503 | pSMB->Reserved = 0; |
| 4304 | pSMB->ParameterOffset = 0; | 4504 | pSMB->ParameterOffset = 0; |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index c467de857610..88f60aa52058 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
| @@ -76,12 +76,19 @@ struct smb_vol { | |||
| 76 | unsigned setuids:1; | 76 | unsigned setuids:1; |
| 77 | unsigned noperm:1; | 77 | unsigned noperm:1; |
| 78 | unsigned no_psx_acl:1; /* set if posix acl support should be disabled */ | 78 | unsigned no_psx_acl:1; /* set if posix acl support should be disabled */ |
| 79 | unsigned cifs_acl:1; | ||
| 79 | unsigned no_xattr:1; /* set if xattr (EA) support should be disabled*/ | 80 | unsigned no_xattr:1; /* set if xattr (EA) support should be disabled*/ |
| 80 | unsigned server_ino:1; /* use inode numbers from server ie UniqueId */ | 81 | unsigned server_ino:1; /* use inode numbers from server ie UniqueId */ |
| 81 | unsigned direct_io:1; | 82 | unsigned direct_io:1; |
| 82 | unsigned remap:1; /* set to remap seven reserved chars in filenames */ | 83 | unsigned remap:1; /* set to remap seven reserved chars in filenames */ |
| 83 | unsigned posix_paths:1; /* unset to not ask for posix pathnames. */ | 84 | unsigned posix_paths:1; /* unset to not ask for posix pathnames. */ |
| 84 | unsigned sfu_emul:1; | 85 | unsigned sfu_emul:1; |
| 86 | unsigned krb5:1; | ||
| 87 | unsigned ntlm:1; | ||
| 88 | unsigned ntlmv2:1; | ||
| 89 | unsigned nullauth:1; /* attempt to authenticate with null user */ | ||
| 90 | unsigned sign:1; | ||
| 91 | unsigned seal:1; /* encrypt */ | ||
| 85 | unsigned nocase; /* request case insensitive filenames */ | 92 | unsigned nocase; /* request case insensitive filenames */ |
| 86 | unsigned nobrl; /* disable sending byte range locks to srv */ | 93 | unsigned nobrl; /* disable sending byte range locks to srv */ |
| 87 | unsigned int rsize; | 94 | unsigned int rsize; |
| @@ -508,7 +515,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
| 508 | /* else length ok */ | 515 | /* else length ok */ |
| 509 | reconnect = 0; | 516 | reconnect = 0; |
| 510 | 517 | ||
| 511 | if(pdu_length > MAX_CIFS_HDR_SIZE - 4) { | 518 | if(pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) { |
| 512 | isLargeBuf = TRUE; | 519 | isLargeBuf = TRUE; |
| 513 | memcpy(bigbuf, smallbuf, 4); | 520 | memcpy(bigbuf, smallbuf, 4); |
| 514 | smb_buffer = bigbuf; | 521 | smb_buffer = bigbuf; |
| @@ -777,7 +784,7 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) | |||
| 777 | 784 | ||
| 778 | /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */ | 785 | /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */ |
| 779 | vol->rw = TRUE; | 786 | vol->rw = TRUE; |
| 780 | 787 | vol->ntlm = TRUE; | |
| 781 | /* default is always to request posix paths. */ | 788 | /* default is always to request posix paths. */ |
| 782 | vol->posix_paths = 1; | 789 | vol->posix_paths = 1; |
| 783 | 790 | ||
| @@ -903,6 +910,39 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) | |||
| 903 | printk(KERN_WARNING "CIFS: ip address too long\n"); | 910 | printk(KERN_WARNING "CIFS: ip address too long\n"); |
| 904 | return 1; | 911 | return 1; |
| 905 | } | 912 | } |
| 913 | } else if (strnicmp(data, "sec", 3) == 0) { | ||
| 914 | if (!value || !*value) { | ||
| 915 | cERROR(1,("no security value specified")); | ||
| 916 | continue; | ||
| 917 | } else if (strnicmp(value, "krb5i", 5) == 0) { | ||
| 918 | vol->sign = 1; | ||
| 919 | vol->krb5 = 1; | ||
| 920 | } else if (strnicmp(value, "krb5p", 5) == 0) { | ||
| 921 | /* vol->seal = 1; | ||
| 922 | vol->krb5 = 1; */ | ||
| 923 | cERROR(1,("Krb5 cifs privacy not supported")); | ||
| 924 | return 1; | ||
| 925 | } else if (strnicmp(value, "krb5", 4) == 0) { | ||
| 926 | vol->krb5 = 1; | ||
| 927 | } else if (strnicmp(value, "ntlmv2i", 7) == 0) { | ||
| 928 | vol->ntlmv2 = 1; | ||
| 929 | vol->sign = 1; | ||
| 930 | } else if (strnicmp(value, "ntlmv2", 6) == 0) { | ||
| 931 | vol->ntlmv2 = 1; | ||
| 932 | } else if (strnicmp(value, "ntlmi", 5) == 0) { | ||
| 933 | vol->ntlm = 1; | ||
| 934 | vol->sign = 1; | ||
| 935 | } else if (strnicmp(value, "ntlm", 4) == 0) { | ||
| 936 | /* ntlm is default so can be turned off too */ | ||
| 937 | vol->ntlm = 1; | ||
| 938 | } else if (strnicmp(value, "nontlm", 6) == 0) { | ||
| 939 | vol->ntlm = 0; | ||
| 940 | } else if (strnicmp(value, "none", 4) == 0) { | ||
| 941 | vol->nullauth = 1; | ||
| 942 | } else { | ||
| 943 | cERROR(1,("bad security option: %s", value)); | ||
| 944 | return 1; | ||
| 945 | } | ||
| 906 | } else if ((strnicmp(data, "unc", 3) == 0) | 946 | } else if ((strnicmp(data, "unc", 3) == 0) |
| 907 | || (strnicmp(data, "target", 6) == 0) | 947 | || (strnicmp(data, "target", 6) == 0) |
| 908 | || (strnicmp(data, "path", 4) == 0)) { | 948 | || (strnicmp(data, "path", 4) == 0)) { |
| @@ -1120,6 +1160,10 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) | |||
| 1120 | vol->server_ino = 1; | 1160 | vol->server_ino = 1; |
| 1121 | } else if (strnicmp(data, "noserverino",9) == 0) { | 1161 | } else if (strnicmp(data, "noserverino",9) == 0) { |
| 1122 | vol->server_ino = 0; | 1162 | vol->server_ino = 0; |
| 1163 | } else if (strnicmp(data, "cifsacl",7) == 0) { | ||
| 1164 | vol->cifs_acl = 1; | ||
| 1165 | } else if (strnicmp(data, "nocifsacl", 9) == 0) { | ||
| 1166 | vol->cifs_acl = 0; | ||
| 1123 | } else if (strnicmp(data, "acl",3) == 0) { | 1167 | } else if (strnicmp(data, "acl",3) == 0) { |
| 1124 | vol->no_psx_acl = 0; | 1168 | vol->no_psx_acl = 0; |
| 1125 | } else if (strnicmp(data, "noacl",5) == 0) { | 1169 | } else if (strnicmp(data, "noacl",5) == 0) { |
| @@ -1546,7 +1590,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
| 1546 | cFYI(1, ("Username: %s ", volume_info.username)); | 1590 | cFYI(1, ("Username: %s ", volume_info.username)); |
| 1547 | 1591 | ||
| 1548 | } else { | 1592 | } else { |
| 1549 | cifserror("No username specified "); | 1593 | cifserror("No username specified"); |
| 1550 | /* In userspace mount helper we can get user name from alternate | 1594 | /* In userspace mount helper we can get user name from alternate |
| 1551 | locations such as env variables and files on disk */ | 1595 | locations such as env variables and files on disk */ |
| 1552 | kfree(volume_info.UNC); | 1596 | kfree(volume_info.UNC); |
| @@ -1587,7 +1631,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
| 1587 | return -EINVAL; | 1631 | return -EINVAL; |
| 1588 | } else /* which servers DFS root would we conect to */ { | 1632 | } else /* which servers DFS root would we conect to */ { |
| 1589 | cERROR(1, | 1633 | cERROR(1, |
| 1590 | ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified ")); | 1634 | ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified")); |
| 1591 | kfree(volume_info.UNC); | 1635 | kfree(volume_info.UNC); |
| 1592 | kfree(volume_info.password); | 1636 | kfree(volume_info.password); |
| 1593 | FreeXid(xid); | 1637 | FreeXid(xid); |
| @@ -1626,7 +1670,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
| 1626 | 1670 | ||
| 1627 | 1671 | ||
| 1628 | if (srvTcp) { | 1672 | if (srvTcp) { |
| 1629 | cFYI(1, ("Existing tcp session with server found ")); | 1673 | cFYI(1, ("Existing tcp session with server found")); |
| 1630 | } else { /* create socket */ | 1674 | } else { /* create socket */ |
| 1631 | if(volume_info.port) | 1675 | if(volume_info.port) |
| 1632 | sin_server.sin_port = htons(volume_info.port); | 1676 | sin_server.sin_port = htons(volume_info.port); |
| @@ -1689,11 +1733,11 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
| 1689 | 1733 | ||
| 1690 | if (existingCifsSes) { | 1734 | if (existingCifsSes) { |
| 1691 | pSesInfo = existingCifsSes; | 1735 | pSesInfo = existingCifsSes; |
| 1692 | cFYI(1, ("Existing smb sess found ")); | 1736 | cFYI(1, ("Existing smb sess found")); |
| 1693 | kfree(volume_info.password); | 1737 | kfree(volume_info.password); |
| 1694 | /* volume_info.UNC freed at end of function */ | 1738 | /* volume_info.UNC freed at end of function */ |
| 1695 | } else if (!rc) { | 1739 | } else if (!rc) { |
| 1696 | cFYI(1, ("Existing smb sess not found ")); | 1740 | cFYI(1, ("Existing smb sess not found")); |
| 1697 | pSesInfo = sesInfoAlloc(); | 1741 | pSesInfo = sesInfoAlloc(); |
| 1698 | if (pSesInfo == NULL) | 1742 | if (pSesInfo == NULL) |
| 1699 | rc = -ENOMEM; | 1743 | rc = -ENOMEM; |
| @@ -1751,7 +1795,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
| 1751 | cifs_sb->mnt_gid = volume_info.linux_gid; | 1795 | cifs_sb->mnt_gid = volume_info.linux_gid; |
| 1752 | cifs_sb->mnt_file_mode = volume_info.file_mode; | 1796 | cifs_sb->mnt_file_mode = volume_info.file_mode; |
| 1753 | cifs_sb->mnt_dir_mode = volume_info.dir_mode; | 1797 | cifs_sb->mnt_dir_mode = volume_info.dir_mode; |
| 1754 | cFYI(1,("file mode: 0x%x dir mode: 0x%x",cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode)); | 1798 | cFYI(1,("file mode: 0x%x dir mode: 0x%x", |
| 1799 | cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode)); | ||
| 1755 | 1800 | ||
| 1756 | if(volume_info.noperm) | 1801 | if(volume_info.noperm) |
| 1757 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM; | 1802 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM; |
| @@ -1767,6 +1812,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
| 1767 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL; | 1812 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL; |
| 1768 | if(volume_info.nobrl) | 1813 | if(volume_info.nobrl) |
| 1769 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL; | 1814 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL; |
| 1815 | if(volume_info.cifs_acl) | ||
| 1816 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL; | ||
| 1770 | 1817 | ||
| 1771 | if(volume_info.direct_io) { | 1818 | if(volume_info.direct_io) { |
| 1772 | cFYI(1,("mounting share using direct i/o")); | 1819 | cFYI(1,("mounting share using direct i/o")); |
| @@ -1777,7 +1824,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
| 1777 | find_unc(sin_server.sin_addr.s_addr, volume_info.UNC, | 1824 | find_unc(sin_server.sin_addr.s_addr, volume_info.UNC, |
| 1778 | volume_info.username); | 1825 | volume_info.username); |
| 1779 | if (tcon) { | 1826 | if (tcon) { |
| 1780 | cFYI(1, ("Found match on UNC path ")); | 1827 | cFYI(1, ("Found match on UNC path")); |
| 1781 | /* we can have only one retry value for a connection | 1828 | /* we can have only one retry value for a connection |
| 1782 | to a share so for resources mounted more than once | 1829 | to a share so for resources mounted more than once |
| 1783 | to the same server share the last value passed in | 1830 | to the same server share the last value passed in |
| @@ -1926,7 +1973,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
| 1926 | __u32 capabilities; | 1973 | __u32 capabilities; |
| 1927 | __u16 count; | 1974 | __u16 count; |
| 1928 | 1975 | ||
| 1929 | cFYI(1, ("In sesssetup ")); | 1976 | cFYI(1, ("In sesssetup")); |
| 1930 | if(ses == NULL) | 1977 | if(ses == NULL) |
| 1931 | return -EINVAL; | 1978 | return -EINVAL; |
| 1932 | user = ses->userName; | 1979 | user = ses->userName; |
| @@ -3202,9 +3249,26 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, | |||
| 3202 | 3249 | ||
| 3203 | pSMB->AndXCommand = 0xFF; | 3250 | pSMB->AndXCommand = 0xFF; |
| 3204 | pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO); | 3251 | pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO); |
| 3205 | pSMB->PasswordLength = cpu_to_le16(1); /* minimum */ | ||
| 3206 | bcc_ptr = &pSMB->Password[0]; | 3252 | bcc_ptr = &pSMB->Password[0]; |
| 3207 | bcc_ptr++; /* skip password */ | 3253 | if((ses->server->secMode) & SECMODE_USER) { |
| 3254 | pSMB->PasswordLength = cpu_to_le16(1); /* minimum */ | ||
| 3255 | bcc_ptr++; /* skip password */ | ||
| 3256 | } else { | ||
| 3257 | pSMB->PasswordLength = cpu_to_le16(CIFS_SESSION_KEY_SIZE); | ||
| 3258 | /* BB FIXME add code to fail this if NTLMv2 or Kerberos | ||
| 3259 | specified as required (when that support is added to | ||
| 3260 | the vfs in the future) as only NTLM or the much | ||
| 3261 | weaker LANMAN (which we do not send) is accepted | ||
| 3262 | by Samba (not sure whether other servers allow | ||
| 3263 | NTLMv2 password here) */ | ||
| 3264 | SMBNTencrypt(ses->password, | ||
| 3265 | ses->server->cryptKey, | ||
| 3266 | bcc_ptr); | ||
| 3267 | |||
| 3268 | bcc_ptr += CIFS_SESSION_KEY_SIZE; | ||
| 3269 | *bcc_ptr = 0; | ||
| 3270 | bcc_ptr++; /* align */ | ||
| 3271 | } | ||
| 3208 | 3272 | ||
| 3209 | if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) | 3273 | if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) |
| 3210 | smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; | 3274 | smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; |
| @@ -3222,7 +3286,6 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, | |||
| 3222 | bcc_ptr += 2 * length; /* convert num of 16 bit words to bytes */ | 3286 | bcc_ptr += 2 * length; /* convert num of 16 bit words to bytes */ |
| 3223 | bcc_ptr += 2; /* skip trailing null */ | 3287 | bcc_ptr += 2; /* skip trailing null */ |
| 3224 | } else { /* ASCII */ | 3288 | } else { /* ASCII */ |
| 3225 | |||
| 3226 | strcpy(bcc_ptr, tree); | 3289 | strcpy(bcc_ptr, tree); |
| 3227 | bcc_ptr += strlen(tree) + 1; | 3290 | bcc_ptr += strlen(tree) + 1; |
| 3228 | } | 3291 | } |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 32cc96cafa3e..fed55e3c53df 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * | 3 | * |
| 4 | * vfs operations that deal with dentries | 4 | * vfs operations that deal with dentries |
| 5 | * | 5 | * |
| 6 | * Copyright (C) International Business Machines Corp., 2002,2003 | 6 | * Copyright (C) International Business Machines Corp., 2002,2005 |
| 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 |
| @@ -200,8 +200,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
| 200 | (oplock & CIFS_CREATE_ACTION)) | 200 | (oplock & CIFS_CREATE_ACTION)) |
| 201 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 201 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
| 202 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, | 202 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, |
| 203 | (__u64)current->euid, | 203 | (__u64)current->fsuid, |
| 204 | (__u64)current->egid, | 204 | (__u64)current->fsgid, |
| 205 | 0 /* dev */, | 205 | 0 /* dev */, |
| 206 | cifs_sb->local_nls, | 206 | cifs_sb->local_nls, |
| 207 | cifs_sb->mnt_cifs_flags & | 207 | cifs_sb->mnt_cifs_flags & |
| @@ -325,7 +325,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, | |||
| 325 | else if (pTcon->ses->capabilities & CAP_UNIX) { | 325 | else if (pTcon->ses->capabilities & CAP_UNIX) { |
| 326 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 326 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
| 327 | rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, | 327 | rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, |
| 328 | mode,(__u64)current->euid,(__u64)current->egid, | 328 | mode,(__u64)current->fsuid,(__u64)current->fsgid, |
| 329 | device_number, cifs_sb->local_nls, | 329 | device_number, cifs_sb->local_nls, |
| 330 | cifs_sb->mnt_cifs_flags & | 330 | cifs_sb->mnt_cifs_flags & |
| 331 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 331 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 5ade53d7bca8..77c990f0cb98 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
| @@ -553,13 +553,13 @@ int cifs_closedir(struct inode *inode, struct file *file) | |||
| 553 | } | 553 | } |
| 554 | ptmp = pCFileStruct->srch_inf.ntwrk_buf_start; | 554 | ptmp = pCFileStruct->srch_inf.ntwrk_buf_start; |
| 555 | if (ptmp) { | 555 | if (ptmp) { |
| 556 | /* BB removeme BB */ cFYI(1, ("freeing smb buf in srch struct in closedir")); | 556 | cFYI(1, ("closedir free smb buf in srch struct")); |
| 557 | pCFileStruct->srch_inf.ntwrk_buf_start = NULL; | 557 | pCFileStruct->srch_inf.ntwrk_buf_start = NULL; |
| 558 | cifs_buf_release(ptmp); | 558 | cifs_buf_release(ptmp); |
| 559 | } | 559 | } |
| 560 | ptmp = pCFileStruct->search_resume_name; | 560 | ptmp = pCFileStruct->search_resume_name; |
| 561 | if (ptmp) { | 561 | if (ptmp) { |
| 562 | /* BB removeme BB */ cFYI(1, ("freeing resume name in closedir")); | 562 | cFYI(1, ("closedir free resume name")); |
| 563 | pCFileStruct->search_resume_name = NULL; | 563 | pCFileStruct->search_resume_name = NULL; |
| 564 | kfree(ptmp); | 564 | kfree(ptmp); |
| 565 | } | 565 | } |
| @@ -868,10 +868,9 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
| 868 | if (rc != 0) | 868 | if (rc != 0) |
| 869 | break; | 869 | break; |
| 870 | } | 870 | } |
| 871 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
| 872 | /* BB FIXME We can not sign across two buffers yet */ | 871 | /* BB FIXME We can not sign across two buffers yet */ |
| 873 | if((experimEnabled) && ((pTcon->ses->server->secMode & | 872 | if((pTcon->ses->server->secMode & |
| 874 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0)) { | 873 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0) { |
| 875 | struct kvec iov[2]; | 874 | struct kvec iov[2]; |
| 876 | unsigned int len; | 875 | unsigned int len; |
| 877 | 876 | ||
| @@ -887,7 +886,6 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
| 887 | iov, 1, long_op); | 886 | iov, 1, long_op); |
| 888 | } else | 887 | } else |
| 889 | /* BB FIXME fixup indentation of line below */ | 888 | /* BB FIXME fixup indentation of line below */ |
| 890 | #endif | ||
| 891 | rc = CIFSSMBWrite(xid, pTcon, | 889 | rc = CIFSSMBWrite(xid, pTcon, |
| 892 | open_file->netfid, | 890 | open_file->netfid, |
| 893 | min_t(const int, cifs_sb->wsize, | 891 | min_t(const int, cifs_sb->wsize, |
| @@ -1024,7 +1022,6 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) | |||
| 1024 | return rc; | 1022 | return rc; |
| 1025 | } | 1023 | } |
| 1026 | 1024 | ||
| 1027 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
| 1028 | static int cifs_writepages(struct address_space *mapping, | 1025 | static int cifs_writepages(struct address_space *mapping, |
| 1029 | struct writeback_control *wbc) | 1026 | struct writeback_control *wbc) |
| 1030 | { | 1027 | { |
| @@ -1227,7 +1224,6 @@ retry: | |||
| 1227 | 1224 | ||
| 1228 | return rc; | 1225 | return rc; |
| 1229 | } | 1226 | } |
| 1230 | #endif | ||
| 1231 | 1227 | ||
| 1232 | static int cifs_writepage(struct page* page, struct writeback_control *wbc) | 1228 | static int cifs_writepage(struct page* page, struct writeback_control *wbc) |
| 1233 | { | 1229 | { |
| @@ -1426,6 +1422,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, | |||
| 1426 | rc = -EAGAIN; | 1422 | rc = -EAGAIN; |
| 1427 | smb_read_data = NULL; | 1423 | smb_read_data = NULL; |
| 1428 | while (rc == -EAGAIN) { | 1424 | while (rc == -EAGAIN) { |
| 1425 | int buf_type = CIFS_NO_BUFFER; | ||
| 1429 | if ((open_file->invalidHandle) && | 1426 | if ((open_file->invalidHandle) && |
| 1430 | (!open_file->closePend)) { | 1427 | (!open_file->closePend)) { |
| 1431 | rc = cifs_reopen_file(file->f_dentry->d_inode, | 1428 | rc = cifs_reopen_file(file->f_dentry->d_inode, |
| @@ -1434,20 +1431,22 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, | |||
| 1434 | break; | 1431 | break; |
| 1435 | } | 1432 | } |
| 1436 | rc = CIFSSMBRead(xid, pTcon, | 1433 | rc = CIFSSMBRead(xid, pTcon, |
| 1437 | open_file->netfid, | 1434 | open_file->netfid, |
| 1438 | current_read_size, *poffset, | 1435 | current_read_size, *poffset, |
| 1439 | &bytes_read, &smb_read_data); | 1436 | &bytes_read, &smb_read_data, |
| 1437 | &buf_type); | ||
| 1440 | pSMBr = (struct smb_com_read_rsp *)smb_read_data; | 1438 | pSMBr = (struct smb_com_read_rsp *)smb_read_data; |
| 1441 | if (copy_to_user(current_offset, | 1439 | if (copy_to_user(current_offset, |
| 1442 | smb_read_data + 4 /* RFC1001 hdr */ | 1440 | smb_read_data + 4 /* RFC1001 hdr */ |
| 1443 | + le16_to_cpu(pSMBr->DataOffset), | 1441 | + le16_to_cpu(pSMBr->DataOffset), |
| 1444 | bytes_read)) { | 1442 | bytes_read)) { |
| 1445 | rc = -EFAULT; | 1443 | rc = -EFAULT; |
| 1446 | FreeXid(xid); | 1444 | } |
| 1447 | return rc; | ||
| 1448 | } | ||
| 1449 | if (smb_read_data) { | 1445 | if (smb_read_data) { |
| 1450 | cifs_buf_release(smb_read_data); | 1446 | if(buf_type == CIFS_SMALL_BUFFER) |
| 1447 | cifs_small_buf_release(smb_read_data); | ||
| 1448 | else if(buf_type == CIFS_LARGE_BUFFER) | ||
| 1449 | cifs_buf_release(smb_read_data); | ||
| 1451 | smb_read_data = NULL; | 1450 | smb_read_data = NULL; |
| 1452 | } | 1451 | } |
| 1453 | } | 1452 | } |
| @@ -1480,6 +1479,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, | |||
| 1480 | int xid; | 1479 | int xid; |
| 1481 | char *current_offset; | 1480 | char *current_offset; |
| 1482 | struct cifsFileInfo *open_file; | 1481 | struct cifsFileInfo *open_file; |
| 1482 | int buf_type = CIFS_NO_BUFFER; | ||
| 1483 | 1483 | ||
| 1484 | xid = GetXid(); | 1484 | xid = GetXid(); |
| 1485 | cifs_sb = CIFS_SB(file->f_dentry->d_sb); | 1485 | cifs_sb = CIFS_SB(file->f_dentry->d_sb); |
| @@ -1516,9 +1516,10 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, | |||
| 1516 | break; | 1516 | break; |
| 1517 | } | 1517 | } |
| 1518 | rc = CIFSSMBRead(xid, pTcon, | 1518 | rc = CIFSSMBRead(xid, pTcon, |
| 1519 | open_file->netfid, | 1519 | open_file->netfid, |
| 1520 | current_read_size, *poffset, | 1520 | current_read_size, *poffset, |
| 1521 | &bytes_read, ¤t_offset); | 1521 | &bytes_read, ¤t_offset, |
| 1522 | &buf_type); | ||
| 1522 | } | 1523 | } |
| 1523 | if (rc || (bytes_read == 0)) { | 1524 | if (rc || (bytes_read == 0)) { |
| 1524 | if (total_read) { | 1525 | if (total_read) { |
| @@ -1616,6 +1617,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
| 1616 | struct smb_com_read_rsp *pSMBr; | 1617 | struct smb_com_read_rsp *pSMBr; |
| 1617 | struct pagevec lru_pvec; | 1618 | struct pagevec lru_pvec; |
| 1618 | struct cifsFileInfo *open_file; | 1619 | struct cifsFileInfo *open_file; |
| 1620 | int buf_type = CIFS_NO_BUFFER; | ||
| 1619 | 1621 | ||
| 1620 | xid = GetXid(); | 1622 | xid = GetXid(); |
| 1621 | if (file->private_data == NULL) { | 1623 | if (file->private_data == NULL) { |
| @@ -1672,14 +1674,17 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
| 1672 | } | 1674 | } |
| 1673 | 1675 | ||
| 1674 | rc = CIFSSMBRead(xid, pTcon, | 1676 | rc = CIFSSMBRead(xid, pTcon, |
| 1675 | open_file->netfid, | 1677 | open_file->netfid, |
| 1676 | read_size, offset, | 1678 | read_size, offset, |
| 1677 | &bytes_read, &smb_read_data); | 1679 | &bytes_read, &smb_read_data, |
| 1678 | 1680 | &buf_type); | |
| 1679 | /* BB more RC checks ? */ | 1681 | /* BB more RC checks ? */ |
| 1680 | if (rc== -EAGAIN) { | 1682 | if (rc== -EAGAIN) { |
| 1681 | if (smb_read_data) { | 1683 | if (smb_read_data) { |
| 1682 | cifs_buf_release(smb_read_data); | 1684 | if(buf_type == CIFS_SMALL_BUFFER) |
| 1685 | cifs_small_buf_release(smb_read_data); | ||
| 1686 | else if(buf_type == CIFS_LARGE_BUFFER) | ||
| 1687 | cifs_buf_release(smb_read_data); | ||
| 1683 | smb_read_data = NULL; | 1688 | smb_read_data = NULL; |
| 1684 | } | 1689 | } |
| 1685 | } | 1690 | } |
| @@ -1736,7 +1741,10 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
| 1736 | break; | 1741 | break; |
| 1737 | } | 1742 | } |
| 1738 | if (smb_read_data) { | 1743 | if (smb_read_data) { |
| 1739 | cifs_buf_release(smb_read_data); | 1744 | if(buf_type == CIFS_SMALL_BUFFER) |
| 1745 | cifs_small_buf_release(smb_read_data); | ||
| 1746 | else if(buf_type == CIFS_LARGE_BUFFER) | ||
| 1747 | cifs_buf_release(smb_read_data); | ||
| 1740 | smb_read_data = NULL; | 1748 | smb_read_data = NULL; |
| 1741 | } | 1749 | } |
| 1742 | bytes_read = 0; | 1750 | bytes_read = 0; |
| @@ -1746,7 +1754,10 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
| 1746 | 1754 | ||
| 1747 | /* need to free smb_read_data buf before exit */ | 1755 | /* need to free smb_read_data buf before exit */ |
| 1748 | if (smb_read_data) { | 1756 | if (smb_read_data) { |
| 1749 | cifs_buf_release(smb_read_data); | 1757 | if(buf_type == CIFS_SMALL_BUFFER) |
| 1758 | cifs_small_buf_release(smb_read_data); | ||
| 1759 | else if(buf_type == CIFS_LARGE_BUFFER) | ||
| 1760 | cifs_buf_release(smb_read_data); | ||
| 1750 | smb_read_data = NULL; | 1761 | smb_read_data = NULL; |
| 1751 | } | 1762 | } |
| 1752 | 1763 | ||
| @@ -1825,10 +1836,20 @@ int is_size_safe_to_change(struct cifsInodeInfo *cifsInode) | |||
| 1825 | open_file = find_writable_file(cifsInode); | 1836 | open_file = find_writable_file(cifsInode); |
| 1826 | 1837 | ||
| 1827 | if(open_file) { | 1838 | if(open_file) { |
| 1839 | struct cifs_sb_info *cifs_sb; | ||
| 1840 | |||
| 1828 | /* there is not actually a write pending so let | 1841 | /* there is not actually a write pending so let |
| 1829 | this handle go free and allow it to | 1842 | this handle go free and allow it to |
| 1830 | be closable if needed */ | 1843 | be closable if needed */ |
| 1831 | atomic_dec(&open_file->wrtPending); | 1844 | atomic_dec(&open_file->wrtPending); |
| 1845 | |||
| 1846 | cifs_sb = CIFS_SB(cifsInode->vfs_inode.i_sb); | ||
| 1847 | if ( cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO ) { | ||
| 1848 | /* since no page cache to corrupt on directio | ||
| 1849 | we can change size safely */ | ||
| 1850 | return 1; | ||
| 1851 | } | ||
| 1852 | |||
| 1832 | return 0; | 1853 | return 0; |
| 1833 | } else | 1854 | } else |
| 1834 | return 1; | 1855 | return 1; |
| @@ -1873,9 +1894,7 @@ struct address_space_operations cifs_addr_ops = { | |||
| 1873 | .readpage = cifs_readpage, | 1894 | .readpage = cifs_readpage, |
| 1874 | .readpages = cifs_readpages, | 1895 | .readpages = cifs_readpages, |
| 1875 | .writepage = cifs_writepage, | 1896 | .writepage = cifs_writepage, |
| 1876 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
| 1877 | .writepages = cifs_writepages, | 1897 | .writepages = cifs_writepages, |
| 1878 | #endif | ||
| 1879 | .prepare_write = cifs_prepare_write, | 1898 | .prepare_write = cifs_prepare_write, |
| 1880 | .commit_write = cifs_commit_write, | 1899 | .commit_write = cifs_commit_write, |
| 1881 | .set_page_dirty = __set_page_dirty_nobuffers, | 1900 | .set_page_dirty = __set_page_dirty_nobuffers, |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 3ebce9430f4a..59359911f481 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
| @@ -229,11 +229,12 @@ static int decode_sfu_inode(struct inode * inode, __u64 size, | |||
| 229 | cifs_sb->mnt_cifs_flags & | 229 | cifs_sb->mnt_cifs_flags & |
| 230 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 230 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
| 231 | if (rc==0) { | 231 | if (rc==0) { |
| 232 | int buf_type = CIFS_NO_BUFFER; | ||
| 232 | /* Read header */ | 233 | /* Read header */ |
| 233 | rc = CIFSSMBRead(xid, pTcon, | 234 | rc = CIFSSMBRead(xid, pTcon, |
| 234 | netfid, | 235 | netfid, |
| 235 | 24 /* length */, 0 /* offset */, | 236 | 24 /* length */, 0 /* offset */, |
| 236 | &bytes_read, &pbuf); | 237 | &bytes_read, &pbuf, &buf_type); |
| 237 | if((rc == 0) && (bytes_read >= 8)) { | 238 | if((rc == 0) && (bytes_read >= 8)) { |
| 238 | if(memcmp("IntxBLK", pbuf, 8) == 0) { | 239 | if(memcmp("IntxBLK", pbuf, 8) == 0) { |
| 239 | cFYI(1,("Block device")); | 240 | cFYI(1,("Block device")); |
| @@ -267,7 +268,7 @@ static int decode_sfu_inode(struct inode * inode, __u64 size, | |||
| 267 | } else { | 268 | } else { |
| 268 | inode->i_mode |= S_IFREG; /* then it is a file */ | 269 | inode->i_mode |= S_IFREG; /* then it is a file */ |
| 269 | rc = -EOPNOTSUPP; /* or some unknown SFU type */ | 270 | rc = -EOPNOTSUPP; /* or some unknown SFU type */ |
| 270 | } | 271 | } |
| 271 | CIFSSMBClose(xid, pTcon, netfid); | 272 | CIFSSMBClose(xid, pTcon, netfid); |
| 272 | } | 273 | } |
| 273 | return rc; | 274 | return rc; |
| @@ -750,8 +751,8 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) | |||
| 750 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 751 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
| 751 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, | 752 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, |
| 752 | mode, | 753 | mode, |
| 753 | (__u64)current->euid, | 754 | (__u64)current->fsuid, |
| 754 | (__u64)current->egid, | 755 | (__u64)current->fsgid, |
| 755 | 0 /* dev_t */, | 756 | 0 /* dev_t */, |
| 756 | cifs_sb->local_nls, | 757 | cifs_sb->local_nls, |
| 757 | cifs_sb->mnt_cifs_flags & | 758 | cifs_sb->mnt_cifs_flags & |
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 94baf6c8ecbd..812c6bb0fe38 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,2004 | 4 | * Copyright (C) International Business Machines Corp., 2002,2005 |
| 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 |
| @@ -161,6 +161,9 @@ cifs_buf_get(void) | |||
| 161 | if (ret_buf) { | 161 | if (ret_buf) { |
| 162 | memset(ret_buf, 0, sizeof(struct smb_hdr) + 3); | 162 | memset(ret_buf, 0, sizeof(struct smb_hdr) + 3); |
| 163 | atomic_inc(&bufAllocCount); | 163 | atomic_inc(&bufAllocCount); |
| 164 | #ifdef CONFIG_CIFS_STATS2 | ||
| 165 | atomic_inc(&totBufAllocCount); | ||
| 166 | #endif /* CONFIG_CIFS_STATS2 */ | ||
| 164 | } | 167 | } |
| 165 | 168 | ||
| 166 | return ret_buf; | 169 | return ret_buf; |
| @@ -195,6 +198,10 @@ cifs_small_buf_get(void) | |||
| 195 | /* No need to clear memory here, cleared in header assemble */ | 198 | /* No need to clear memory here, cleared in header assemble */ |
| 196 | /* memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);*/ | 199 | /* memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);*/ |
| 197 | atomic_inc(&smBufAllocCount); | 200 | atomic_inc(&smBufAllocCount); |
| 201 | #ifdef CONFIG_CIFS_STATS2 | ||
| 202 | atomic_inc(&totSmBufAllocCount); | ||
| 203 | #endif /* CONFIG_CIFS_STATS2 */ | ||
| 204 | |||
| 198 | } | 205 | } |
| 199 | return ret_buf; | 206 | return ret_buf; |
| 200 | } | 207 | } |
| @@ -292,7 +299,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , | |||
| 292 | struct cifsSesInfo * ses; | 299 | struct cifsSesInfo * ses; |
| 293 | char *temp = (char *) buffer; | 300 | char *temp = (char *) buffer; |
| 294 | 301 | ||
| 295 | memset(temp,0,MAX_CIFS_HDR_SIZE); | 302 | memset(temp,0,256); /* bigger than MAX_CIFS_HDR_SIZE */ |
| 296 | 303 | ||
| 297 | buffer->smb_buf_length = | 304 | buffer->smb_buf_length = |
| 298 | (2 * word_count) + sizeof (struct smb_hdr) - | 305 | (2 * word_count) + sizeof (struct smb_hdr) - |
| @@ -348,12 +355,12 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , | |||
| 348 | /* BB Add support for establishing new tCon and SMB Session */ | 355 | /* BB Add support for establishing new tCon and SMB Session */ |
| 349 | /* with userid/password pairs found on the smb session */ | 356 | /* with userid/password pairs found on the smb session */ |
| 350 | /* for other target tcp/ip addresses BB */ | 357 | /* for other target tcp/ip addresses BB */ |
| 351 | if(current->uid != treeCon->ses->linux_uid) { | 358 | if(current->fsuid != treeCon->ses->linux_uid) { |
| 352 | cFYI(1,("Multiuser mode and UID did not match tcon uid ")); | 359 | cFYI(1,("Multiuser mode and UID did not match tcon uid")); |
| 353 | read_lock(&GlobalSMBSeslock); | 360 | read_lock(&GlobalSMBSeslock); |
| 354 | list_for_each(temp_item, &GlobalSMBSessionList) { | 361 | list_for_each(temp_item, &GlobalSMBSessionList) { |
| 355 | ses = list_entry(temp_item, struct cifsSesInfo, cifsSessionList); | 362 | ses = list_entry(temp_item, struct cifsSesInfo, cifsSessionList); |
| 356 | if(ses->linux_uid == current->uid) { | 363 | if(ses->linux_uid == current->fsuid) { |
| 357 | if(ses->server == treeCon->ses->server) { | 364 | if(ses->server == treeCon->ses->server) { |
| 358 | cFYI(1,("found matching uid substitute right smb_uid")); | 365 | cFYI(1,("found matching uid substitute right smb_uid")); |
| 359 | buffer->Uid = ses->Suid; | 366 | buffer->Uid = ses->Suid; |
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 9bdaaecae36f..288cc048d37f 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
| @@ -214,8 +214,7 @@ static void fill_in_inode(struct inode *tmp_inode, | |||
| 214 | tmp_inode->i_fop = &cifs_file_nobrl_ops; | 214 | tmp_inode->i_fop = &cifs_file_nobrl_ops; |
| 215 | else | 215 | else |
| 216 | tmp_inode->i_fop = &cifs_file_ops; | 216 | tmp_inode->i_fop = &cifs_file_ops; |
| 217 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | 217 | |
| 218 | tmp_inode->i_fop->lock = NULL; | ||
| 219 | tmp_inode->i_data.a_ops = &cifs_addr_ops; | 218 | tmp_inode->i_data.a_ops = &cifs_addr_ops; |
| 220 | if((cifs_sb->tcon) && (cifs_sb->tcon->ses) && | 219 | if((cifs_sb->tcon) && (cifs_sb->tcon->ses) && |
| 221 | (cifs_sb->tcon->ses->server->maxBuf < | 220 | (cifs_sb->tcon->ses->server->maxBuf < |
| @@ -327,12 +326,18 @@ static void unix_fill_in_inode(struct inode *tmp_inode, | |||
| 327 | if (S_ISREG(tmp_inode->i_mode)) { | 326 | if (S_ISREG(tmp_inode->i_mode)) { |
| 328 | cFYI(1, ("File inode")); | 327 | cFYI(1, ("File inode")); |
| 329 | tmp_inode->i_op = &cifs_file_inode_ops; | 328 | tmp_inode->i_op = &cifs_file_inode_ops; |
| 330 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) | 329 | |
| 331 | tmp_inode->i_fop = &cifs_file_direct_ops; | 330 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { |
| 331 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | ||
| 332 | tmp_inode->i_fop = &cifs_file_direct_nobrl_ops; | ||
| 333 | else | ||
| 334 | tmp_inode->i_fop = &cifs_file_direct_ops; | ||
| 335 | |||
| 336 | } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | ||
| 337 | tmp_inode->i_fop = &cifs_file_nobrl_ops; | ||
| 332 | else | 338 | else |
| 333 | tmp_inode->i_fop = &cifs_file_ops; | 339 | tmp_inode->i_fop = &cifs_file_ops; |
| 334 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | 340 | |
| 335 | tmp_inode->i_fop->lock = NULL; | ||
| 336 | tmp_inode->i_data.a_ops = &cifs_addr_ops; | 341 | tmp_inode->i_data.a_ops = &cifs_addr_ops; |
| 337 | if((cifs_sb->tcon) && (cifs_sb->tcon->ses) && | 342 | if((cifs_sb->tcon) && (cifs_sb->tcon->ses) && |
| 338 | (cifs_sb->tcon->ses->server->maxBuf < | 343 | (cifs_sb->tcon->ses->server->maxBuf < |
diff --git a/fs/cifs/rfc1002pdu.h b/fs/cifs/rfc1002pdu.h index 9222033cad8e..aede606132aa 100644 --- a/fs/cifs/rfc1002pdu.h +++ b/fs/cifs/rfc1002pdu.h | |||
| @@ -24,11 +24,11 @@ | |||
| 24 | /* NB: unlike smb/cifs packets, the RFC1002 structures are big endian */ | 24 | /* NB: unlike smb/cifs packets, the RFC1002 structures are big endian */ |
| 25 | 25 | ||
| 26 | /* RFC 1002 session packet types */ | 26 | /* RFC 1002 session packet types */ |
| 27 | #define RFC1002_SESSION_MESASAGE 0x00 | 27 | #define RFC1002_SESSION_MESSAGE 0x00 |
| 28 | #define RFC1002_SESSION_REQUEST 0x81 | 28 | #define RFC1002_SESSION_REQUEST 0x81 |
| 29 | #define RFC1002_POSITIVE_SESSION_RESPONSE 0x82 | 29 | #define RFC1002_POSITIVE_SESSION_RESPONSE 0x82 |
| 30 | #define RFC1002_NEGATIVE_SESSION_RESPONSE 0x83 | 30 | #define RFC1002_NEGATIVE_SESSION_RESPONSE 0x83 |
| 31 | #define RFC1002_RETARGET_SESSION_RESPONSE 0x83 | 31 | #define RFC1002_RETARGET_SESSION_RESPONSE 0x84 |
| 32 | #define RFC1002_SESSION_KEEP_ALIVE 0x85 | 32 | #define RFC1002_SESSION_KEEP_ALIVE 0x85 |
| 33 | 33 | ||
| 34 | /* RFC 1002 flags (only one defined */ | 34 | /* RFC 1002 flags (only one defined */ |
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index f8871196098c..7b98792150ea 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c | |||
| @@ -206,7 +206,6 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, | |||
| 206 | return rc; | 206 | return rc; |
| 207 | } | 207 | } |
| 208 | 208 | ||
| 209 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
| 210 | static int | 209 | static int |
| 211 | smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec, | 210 | smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec, |
| 212 | struct sockaddr *sin) | 211 | struct sockaddr *sin) |
| @@ -299,7 +298,7 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec, | |||
| 299 | 298 | ||
| 300 | int | 299 | int |
| 301 | SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, | 300 | SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, |
| 302 | struct kvec *iov, int n_vec, int *pbytes_returned, | 301 | struct kvec *iov, int n_vec, int * pRespBufType /* ret */, |
| 303 | const int long_op) | 302 | const int long_op) |
| 304 | { | 303 | { |
| 305 | int rc = 0; | 304 | int rc = 0; |
| @@ -307,6 +306,8 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, | |||
| 307 | unsigned long timeout; | 306 | unsigned long timeout; |
| 308 | struct mid_q_entry *midQ; | 307 | struct mid_q_entry *midQ; |
| 309 | struct smb_hdr *in_buf = iov[0].iov_base; | 308 | struct smb_hdr *in_buf = iov[0].iov_base; |
| 309 | |||
| 310 | *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */ | ||
| 310 | 311 | ||
| 311 | if (ses == NULL) { | 312 | if (ses == NULL) { |
| 312 | cERROR(1,("Null smb session")); | 313 | cERROR(1,("Null smb session")); |
| @@ -392,8 +393,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, | |||
| 392 | return -ENOMEM; | 393 | return -ENOMEM; |
| 393 | } | 394 | } |
| 394 | 395 | ||
| 395 | /* BB FIXME */ | 396 | rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number); |
| 396 | /* rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number); */ | ||
| 397 | 397 | ||
| 398 | midQ->midState = MID_REQUEST_SUBMITTED; | 398 | midQ->midState = MID_REQUEST_SUBMITTED; |
| 399 | #ifdef CONFIG_CIFS_STATS2 | 399 | #ifdef CONFIG_CIFS_STATS2 |
| @@ -489,21 +489,23 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, | |||
| 489 | receive_len, xid)); | 489 | receive_len, xid)); |
| 490 | rc = -EIO; | 490 | rc = -EIO; |
| 491 | } else { /* rcvd frame is ok */ | 491 | } else { /* rcvd frame is ok */ |
| 492 | |||
| 493 | if (midQ->resp_buf && | 492 | if (midQ->resp_buf && |
| 494 | (midQ->midState == MID_RESPONSE_RECEIVED)) { | 493 | (midQ->midState == MID_RESPONSE_RECEIVED)) { |
| 495 | in_buf->smb_buf_length = receive_len; | ||
| 496 | /* BB verify that length would not overrun small buf */ | ||
| 497 | memcpy((char *)in_buf + 4, | ||
| 498 | (char *)midQ->resp_buf + 4, | ||
| 499 | receive_len); | ||
| 500 | 494 | ||
| 501 | dump_smb(in_buf, 80); | 495 | iov[0].iov_base = (char *)midQ->resp_buf; |
| 496 | if(midQ->largeBuf) | ||
| 497 | *pRespBufType = CIFS_LARGE_BUFFER; | ||
| 498 | else | ||
| 499 | *pRespBufType = CIFS_SMALL_BUFFER; | ||
| 500 | iov[0].iov_len = receive_len + 4; | ||
| 501 | iov[1].iov_len = 0; | ||
| 502 | |||
| 503 | dump_smb(midQ->resp_buf, 80); | ||
| 502 | /* convert the length into a more usable form */ | 504 | /* convert the length into a more usable form */ |
| 503 | if((receive_len > 24) && | 505 | if((receive_len > 24) && |
| 504 | (ses->server->secMode & (SECMODE_SIGN_REQUIRED | | 506 | (ses->server->secMode & (SECMODE_SIGN_REQUIRED | |
| 505 | SECMODE_SIGN_ENABLED))) { | 507 | SECMODE_SIGN_ENABLED))) { |
| 506 | rc = cifs_verify_signature(in_buf, | 508 | rc = cifs_verify_signature(midQ->resp_buf, |
| 507 | ses->server->mac_signing_key, | 509 | ses->server->mac_signing_key, |
| 508 | midQ->sequence_number+1); | 510 | midQ->sequence_number+1); |
| 509 | if(rc) { | 511 | if(rc) { |
| @@ -512,18 +514,19 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, | |||
| 512 | } | 514 | } |
| 513 | } | 515 | } |
| 514 | 516 | ||
| 515 | *pbytes_returned = in_buf->smb_buf_length; | ||
| 516 | |||
| 517 | /* BB special case reconnect tid and uid here? */ | 517 | /* BB special case reconnect tid and uid here? */ |
| 518 | /* BB special case Errbadpassword and pwdexpired here */ | 518 | /* BB special case Errbadpassword and pwdexpired here */ |
| 519 | rc = map_smb_to_linux_error(in_buf); | 519 | rc = map_smb_to_linux_error(midQ->resp_buf); |
| 520 | 520 | ||
| 521 | /* convert ByteCount if necessary */ | 521 | /* convert ByteCount if necessary */ |
| 522 | if (receive_len >= | 522 | if (receive_len >= |
| 523 | sizeof (struct smb_hdr) - | 523 | sizeof (struct smb_hdr) - |
| 524 | 4 /* do not count RFC1001 header */ + | 524 | 4 /* do not count RFC1001 header */ + |
| 525 | (2 * in_buf->WordCount) + 2 /* bcc */ ) | 525 | (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ ) |
| 526 | BCC(in_buf) = le16_to_cpu(BCC_LE(in_buf)); | 526 | BCC(midQ->resp_buf) = |
| 527 | le16_to_cpu(BCC_LE(midQ->resp_buf)); | ||
| 528 | midQ->resp_buf = NULL; /* mark it so will not be freed | ||
| 529 | by DeleteMidQEntry */ | ||
| 527 | } else { | 530 | } else { |
| 528 | rc = -EIO; | 531 | rc = -EIO; |
| 529 | cFYI(1,("Bad MID state?")); | 532 | cFYI(1,("Bad MID state?")); |
| @@ -549,7 +552,6 @@ out_unlock2: | |||
| 549 | 552 | ||
| 550 | return rc; | 553 | return rc; |
| 551 | } | 554 | } |
| 552 | #endif /* CIFS_EXPERIMENTAL */ | ||
| 553 | 555 | ||
| 554 | int | 556 | int |
| 555 | SendReceive(const unsigned int xid, struct cifsSesInfo *ses, | 557 | SendReceive(const unsigned int xid, struct cifsSesInfo *ses, |
| @@ -790,7 +792,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, | |||
| 790 | BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf)); | 792 | BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf)); |
| 791 | } else { | 793 | } else { |
| 792 | rc = -EIO; | 794 | rc = -EIO; |
| 793 | cERROR(1,("Bad MID state? ")); | 795 | cERROR(1,("Bad MID state?")); |
| 794 | } | 796 | } |
| 795 | } | 797 | } |
| 796 | cifs_no_response_exit: | 798 | cifs_no_response_exit: |
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index f375f87c7dbd..777e3363c2a4 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c | |||
| @@ -254,7 +254,8 @@ ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name, | |||
| 254 | rc = CIFSSMBQueryEA(xid,pTcon,full_path,ea_name,ea_value, | 254 | rc = CIFSSMBQueryEA(xid,pTcon,full_path,ea_name,ea_value, |
| 255 | buf_size, cifs_sb->local_nls, | 255 | buf_size, cifs_sb->local_nls, |
| 256 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | 256 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
| 257 | } else if(strncmp(ea_name,POSIX_ACL_XATTR_ACCESS,strlen(POSIX_ACL_XATTR_ACCESS)) == 0) { | 257 | } else if(strncmp(ea_name,POSIX_ACL_XATTR_ACCESS, |
| 258 | strlen(POSIX_ACL_XATTR_ACCESS)) == 0) { | ||
| 258 | #ifdef CONFIG_CIFS_POSIX | 259 | #ifdef CONFIG_CIFS_POSIX |
| 259 | if(sb->s_flags & MS_POSIXACL) | 260 | if(sb->s_flags & MS_POSIXACL) |
| 260 | rc = CIFSSMBGetPosixACL(xid, pTcon, full_path, | 261 | rc = CIFSSMBGetPosixACL(xid, pTcon, full_path, |
| @@ -262,10 +263,27 @@ ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name, | |||
| 262 | cifs_sb->local_nls, | 263 | cifs_sb->local_nls, |
| 263 | cifs_sb->mnt_cifs_flags & | 264 | cifs_sb->mnt_cifs_flags & |
| 264 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 265 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
| 266 | /* else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | ||
| 267 | __u16 fid; | ||
| 268 | int oplock = FALSE; | ||
| 269 | rc = CIFSSMBOpen(xid, pTcon, full_path, | ||
| 270 | FILE_OPEN, GENERIC_READ, 0, &fid, | ||
| 271 | &oplock, NULL, cifs_sb->local_nls, | ||
| 272 | cifs_sb->mnt_cifs_flags & | ||
| 273 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
| 274 | if(rc == 0) { | ||
| 275 | rc = CIFSSMBGetCIFSACL(xid, pTcon, fid, | ||
| 276 | ea_value, buf_size, | ||
| 277 | ACL_TYPE_ACCESS); | ||
| 278 | CIFSSMBClose(xid, pTcon, fid) | ||
| 279 | } | ||
| 280 | } */ /* BB enable after fixing up return data */ | ||
| 281 | |||
| 265 | #else | 282 | #else |
| 266 | cFYI(1,("query POSIX ACL not supported yet")); | 283 | cFYI(1,("query POSIX ACL not supported yet")); |
| 267 | #endif /* CONFIG_CIFS_POSIX */ | 284 | #endif /* CONFIG_CIFS_POSIX */ |
| 268 | } else if(strncmp(ea_name,POSIX_ACL_XATTR_DEFAULT,strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) { | 285 | } else if(strncmp(ea_name,POSIX_ACL_XATTR_DEFAULT, |
| 286 | strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) { | ||
| 269 | #ifdef CONFIG_CIFS_POSIX | 287 | #ifdef CONFIG_CIFS_POSIX |
| 270 | if(sb->s_flags & MS_POSIXACL) | 288 | if(sb->s_flags & MS_POSIXACL) |
| 271 | rc = CIFSSMBGetPosixACL(xid, pTcon, full_path, | 289 | rc = CIFSSMBGetPosixACL(xid, pTcon, full_path, |
