aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/CHANGES3
-rw-r--r--fs/cifs/README9
-rw-r--r--fs/cifs/cifs_dfs_ref.c2
-rw-r--r--fs/cifs/cifsacl.c14
-rw-r--r--fs/cifs/cifsacl.h1
-rw-r--r--fs/cifs/cifsfs.h2
-rw-r--r--fs/cifs/cifspdu.h118
-rw-r--r--fs/cifs/cifsproto.h1
-rw-r--r--fs/cifs/cifssmb.c32
-rw-r--r--fs/cifs/connect.c1
-rw-r--r--fs/cifs/inode.c15
-rw-r--r--fs/cifs/transport.c18
12 files changed, 173 insertions, 43 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index dbd91461853c..05c9da6181c3 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -8,7 +8,8 @@ of second share to disconnected server session (autoreconnect on this).
8Add ability to modify cifs acls for handling chmod (when mounted with 8Add ability to modify cifs acls for handling chmod (when mounted with
9cifsacl flag). Fix prefixpath path separator so we can handle mounts 9cifsacl flag). Fix prefixpath path separator so we can handle mounts
10with prefixpaths longer than one directory (one path component) when 10with prefixpaths longer than one directory (one path component) when
11mounted to Windows servers. 11mounted to Windows servers. Fix slow file open when cifsacl
12enabled.
12 13
13Version 1.51 14Version 1.51
14------------ 15------------
diff --git a/fs/cifs/README b/fs/cifs/README
index 50306229b0f9..621aa1a85971 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -3,7 +3,14 @@ features such as hierarchical dfs like namespace, hardlinks, locking and more.
3It was designed to comply with the SNIA CIFS Technical Reference (which 3It was designed to comply with the SNIA CIFS Technical Reference (which
4supersedes the 1992 X/Open SMB Standard) as well as to perform best practice 4supersedes the 1992 X/Open SMB Standard) as well as to perform best practice
5practical interoperability with Windows 2000, Windows XP, Samba and equivalent 5practical interoperability with Windows 2000, Windows XP, Samba and equivalent
6servers. 6servers. This code was developed in participation with the Protocol Freedom
7Information Foundation.
8
9Please see
10 http://protocolfreedom.org/ and
11 http://samba.org/samba/PFIF/
12for more details.
13
7 14
8For questions or bug reports please contact: 15For questions or bug reports please contact:
9 sfrench@samba.org (sfrench@us.ibm.com) 16 sfrench@samba.org (sfrench@us.ibm.com)
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
index 56c924033b78..f53f41ff1665 100644
--- a/fs/cifs/cifs_dfs_ref.c
+++ b/fs/cifs/cifs_dfs_ref.c
@@ -23,7 +23,7 @@
23#include "dns_resolve.h" 23#include "dns_resolve.h"
24#include "cifs_debug.h" 24#include "cifs_debug.h"
25 25
26LIST_HEAD(cifs_dfs_automount_list); 26static LIST_HEAD(cifs_dfs_automount_list);
27 27
28/* 28/*
29 * DFS functions 29 * DFS functions
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index 1cb5b0a9f2ac..e99d4faf5f02 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -516,7 +516,7 @@ static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len,
516 516
517/* Convert permission bits from mode to equivalent CIFS ACL */ 517/* Convert permission bits from mode to equivalent CIFS ACL */
518static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, 518static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
519 int acl_len, struct inode *inode, __u64 nmode) 519 struct inode *inode, __u64 nmode)
520{ 520{
521 int rc = 0; 521 int rc = 0;
522 __u32 dacloffset; 522 __u32 dacloffset;
@@ -692,14 +692,14 @@ void acl_to_uid_mode(struct inode *inode, const char *path, const __u16 *pfid)
692int mode_to_acl(struct inode *inode, const char *path, __u64 nmode) 692int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
693{ 693{
694 int rc = 0; 694 int rc = 0;
695 __u32 acllen = 0; 695 __u32 secdesclen = 0;
696 struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */ 696 struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
697 struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */ 697 struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
698 698
699 cFYI(DBG2, ("set ACL from mode for %s", path)); 699 cFYI(DBG2, ("set ACL from mode for %s", path));
700 700
701 /* Get the security descriptor */ 701 /* Get the security descriptor */
702 pntsd = get_cifs_acl(&acllen, inode, path, NULL); 702 pntsd = get_cifs_acl(&secdesclen, inode, path, NULL);
703 703
704 /* Add three ACEs for owner, group, everyone getting rid of 704 /* Add three ACEs for owner, group, everyone getting rid of
705 other ACEs as chmod disables ACEs and set the security descriptor */ 705 other ACEs as chmod disables ACEs and set the security descriptor */
@@ -709,20 +709,22 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
709 set security descriptor request security descriptor 709 set security descriptor request security descriptor
710 parameters, and secuirty descriptor itself */ 710 parameters, and secuirty descriptor itself */
711 711
712 pnntsd = kmalloc(acllen, GFP_KERNEL); 712 secdesclen = secdesclen < DEFSECDESCLEN ?
713 DEFSECDESCLEN : secdesclen;
714 pnntsd = kmalloc(secdesclen, GFP_KERNEL);
713 if (!pnntsd) { 715 if (!pnntsd) {
714 cERROR(1, ("Unable to allocate security descriptor")); 716 cERROR(1, ("Unable to allocate security descriptor"));
715 kfree(pntsd); 717 kfree(pntsd);
716 return (-ENOMEM); 718 return (-ENOMEM);
717 } 719 }
718 720
719 rc = build_sec_desc(pntsd, pnntsd, acllen, inode, nmode); 721 rc = build_sec_desc(pntsd, pnntsd, inode, nmode);
720 722
721 cFYI(DBG2, ("build_sec_desc rc: %d", rc)); 723 cFYI(DBG2, ("build_sec_desc rc: %d", rc));
722 724
723 if (!rc) { 725 if (!rc) {
724 /* Set the security descriptor */ 726 /* Set the security descriptor */
725 rc = set_cifs_acl(pnntsd, acllen, inode, path); 727 rc = set_cifs_acl(pnntsd, secdesclen, inode, path);
726 cFYI(DBG2, ("set_cifs_acl rc: %d", rc)); 728 cFYI(DBG2, ("set_cifs_acl rc: %d", rc));
727 } 729 }
728 730
diff --git a/fs/cifs/cifsacl.h b/fs/cifs/cifsacl.h
index 93a7c3462ea2..6c8096cf5155 100644
--- a/fs/cifs/cifsacl.h
+++ b/fs/cifs/cifsacl.h
@@ -27,6 +27,7 @@
27#define NUM_SUBAUTHS 5 /* number of sub authority fields */ 27#define NUM_SUBAUTHS 5 /* number of sub authority fields */
28#define NUM_WK_SIDS 7 /* number of well known sids */ 28#define NUM_WK_SIDS 7 /* number of well known sids */
29#define SIDNAMELENGTH 20 /* long enough for the ones we care about */ 29#define SIDNAMELENGTH 20 /* long enough for the ones we care about */
30#define DEFSECDESCLEN 192 /* sec desc len contaiting a dacl with three aces */
30 31
31#define READ_BIT 0x4 32#define READ_BIT 0x4
32#define WRITE_BIT 0x2 33#define WRITE_BIT 0x2
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 68978306c3ca..e1dd9f32e1d7 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -62,11 +62,9 @@ extern int cifs_setattr(struct dentry *, struct iattr *);
62 62
63extern const struct inode_operations cifs_file_inode_ops; 63extern const struct inode_operations cifs_file_inode_ops;
64extern const struct inode_operations cifs_symlink_inode_ops; 64extern const struct inode_operations cifs_symlink_inode_ops;
65extern struct list_head cifs_dfs_automount_list;
66extern struct inode_operations cifs_dfs_referral_inode_operations; 65extern struct inode_operations cifs_dfs_referral_inode_operations;
67 66
68 67
69
70/* Functions related to files and directories */ 68/* Functions related to files and directories */
71extern const struct file_operations cifs_file_ops; 69extern const struct file_operations cifs_file_ops;
72extern const struct file_operations cifs_file_direct_ops; /* if directio mnt */ 70extern const struct file_operations cifs_file_direct_ops; /* if directio mnt */
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index 47f79504f57b..b18c6d43bef3 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,2007 4 * Copyright (c) International Business Machines Corp., 2002,2008
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
@@ -163,7 +163,10 @@
163 path names in response */ 163 path names in response */
164#define SMBFLG2_KNOWS_EAS cpu_to_le16(2) 164#define SMBFLG2_KNOWS_EAS cpu_to_le16(2)
165#define SMBFLG2_SECURITY_SIGNATURE cpu_to_le16(4) 165#define SMBFLG2_SECURITY_SIGNATURE cpu_to_le16(4)
166#define SMBFLG2_COMPRESSED (8)
167#define SMBFLG2_SECURITY_SIGNATURE_REQUIRED (0x10)
166#define SMBFLG2_IS_LONG_NAME cpu_to_le16(0x40) 168#define SMBFLG2_IS_LONG_NAME cpu_to_le16(0x40)
169#define SMBFLG2_REPARSE_PATH (0x400)
167#define SMBFLG2_EXT_SEC cpu_to_le16(0x800) 170#define SMBFLG2_EXT_SEC cpu_to_le16(0x800)
168#define SMBFLG2_DFS cpu_to_le16(0x1000) 171#define SMBFLG2_DFS cpu_to_le16(0x1000)
169#define SMBFLG2_PAGING_IO cpu_to_le16(0x2000) 172#define SMBFLG2_PAGING_IO cpu_to_le16(0x2000)
@@ -305,7 +308,7 @@
305#define FILE_SHARE_DELETE 0x00000004 308#define FILE_SHARE_DELETE 0x00000004
306#define FILE_SHARE_ALL 0x00000007 309#define FILE_SHARE_ALL 0x00000007
307 310
308/* CreateDisposition flags */ 311/* CreateDisposition flags, similar to CreateAction as well */
309#define FILE_SUPERSEDE 0x00000000 312#define FILE_SUPERSEDE 0x00000000
310#define FILE_OPEN 0x00000001 313#define FILE_OPEN 0x00000001
311#define FILE_CREATE 0x00000002 314#define FILE_CREATE 0x00000002
@@ -317,15 +320,25 @@
317#define CREATE_NOT_FILE 0x00000001 /* if set must not be file */ 320#define CREATE_NOT_FILE 0x00000001 /* if set must not be file */
318#define CREATE_WRITE_THROUGH 0x00000002 321#define CREATE_WRITE_THROUGH 0x00000002
319#define CREATE_SEQUENTIAL 0x00000004 322#define CREATE_SEQUENTIAL 0x00000004
320#define CREATE_SYNC_ALERT 0x00000010 323#define CREATE_NO_BUFFER 0x00000008 /* should not buffer on srv */
321#define CREATE_ASYNC_ALERT 0x00000020 324#define CREATE_SYNC_ALERT 0x00000010 /* MBZ */
325#define CREATE_ASYNC_ALERT 0x00000020 /* MBZ */
322#define CREATE_NOT_DIR 0x00000040 /* if set must not be directory */ 326#define CREATE_NOT_DIR 0x00000040 /* if set must not be directory */
327#define CREATE_TREE_CONNECTION 0x00000080 /* should be zero */
328#define CREATE_COMPLETE_IF_OPLK 0x00000100 /* should be zero */
323#define CREATE_NO_EA_KNOWLEDGE 0x00000200 329#define CREATE_NO_EA_KNOWLEDGE 0x00000200
324#define CREATE_EIGHT_DOT_THREE 0x00000400 330#define CREATE_EIGHT_DOT_THREE 0x00000400 /* doc says this is obsolete
331 open for recovery flag - should
332 be zero */
325#define CREATE_RANDOM_ACCESS 0x00000800 333#define CREATE_RANDOM_ACCESS 0x00000800
326#define CREATE_DELETE_ON_CLOSE 0x00001000 334#define CREATE_DELETE_ON_CLOSE 0x00001000
327#define CREATE_OPEN_BY_ID 0x00002000 335#define CREATE_OPEN_BY_ID 0x00002000
336#define CREATE_OPEN_BACKUP_INTN 0x00004000
337#define CREATE_NO_COMPRESSION 0x00008000
338#define CREATE_RESERVE_OPFILTER 0x00100000 /* should be zero */
328#define OPEN_REPARSE_POINT 0x00200000 339#define OPEN_REPARSE_POINT 0x00200000
340#define OPEN_NO_RECALL 0x00400000
341#define OPEN_FREE_SPACE_QUERY 0x00800000 /* should be zero */
329#define CREATE_OPTIONS_MASK 0x007FFFFF 342#define CREATE_OPTIONS_MASK 0x007FFFFF
330#define CREATE_OPTION_SPECIAL 0x20000000 /* system. NB not sent over wire */ 343#define CREATE_OPTION_SPECIAL 0x20000000 /* system. NB not sent over wire */
331 344
@@ -470,7 +483,7 @@ typedef struct lanman_neg_rsp {
470 483
471typedef struct negotiate_rsp { 484typedef struct negotiate_rsp {
472 struct smb_hdr hdr; /* wct = 17 */ 485 struct smb_hdr hdr; /* wct = 17 */
473 __le16 DialectIndex; 486 __le16 DialectIndex; /* 0xFFFF = no dialect acceptable */
474 __u8 SecurityMode; 487 __u8 SecurityMode;
475 __le16 MaxMpxCount; 488 __le16 MaxMpxCount;
476 __le16 MaxNumberVcs; 489 __le16 MaxNumberVcs;
@@ -516,10 +529,11 @@ typedef struct negotiate_rsp {
516#define CAP_INFOLEVEL_PASSTHRU 0x00002000 529#define CAP_INFOLEVEL_PASSTHRU 0x00002000
517#define CAP_LARGE_READ_X 0x00004000 530#define CAP_LARGE_READ_X 0x00004000
518#define CAP_LARGE_WRITE_X 0x00008000 531#define CAP_LARGE_WRITE_X 0x00008000
532#define CAP_LWIO 0x00010000 /* support fctl_srv_req_resume_key */
519#define CAP_UNIX 0x00800000 533#define CAP_UNIX 0x00800000
520#define CAP_RESERVED 0x02000000 534#define CAP_COMPRESSED_DATA 0x02000000
521#define CAP_BULK_TRANSFER 0x20000000 535#define CAP_DYNAMIC_REAUTH 0x20000000
522#define CAP_COMPRESSED_DATA 0x40000000 536#define CAP_PERSISTENT_HANDLES 0x40000000
523#define CAP_EXTENDED_SECURITY 0x80000000 537#define CAP_EXTENDED_SECURITY 0x80000000
524 538
525typedef union smb_com_session_setup_andx { 539typedef union smb_com_session_setup_andx {
@@ -668,9 +682,7 @@ typedef struct smb_com_tconx_req {
668} __attribute__((packed)) TCONX_REQ; 682} __attribute__((packed)) TCONX_REQ;
669 683
670typedef struct smb_com_tconx_rsp { 684typedef struct smb_com_tconx_rsp {
671 struct smb_hdr hdr; /* wct = 3 note that Win2000 has sent wct = 7 685 struct smb_hdr hdr; /* wct = 3 , not extended response */
672 in some cases on responses. Four unspecified
673 words followed OptionalSupport */
674 __u8 AndXCommand; 686 __u8 AndXCommand;
675 __u8 AndXReserved; 687 __u8 AndXReserved;
676 __le16 AndXOffset; 688 __le16 AndXOffset;
@@ -680,13 +692,48 @@ typedef struct smb_com_tconx_rsp {
680 /* STRING NativeFileSystem */ 692 /* STRING NativeFileSystem */
681} __attribute__((packed)) TCONX_RSP; 693} __attribute__((packed)) TCONX_RSP;
682 694
695typedef struct smb_com_tconx_rsp_ext {
696 struct smb_hdr hdr; /* wct = 7, extended response */
697 __u8 AndXCommand;
698 __u8 AndXReserved;
699 __le16 AndXOffset;
700 __le16 OptionalSupport; /* see below */
701 __le32 MaximalShareAccessRights;
702 __le32 GuestMaximalShareAccessRights;
703 __u16 ByteCount;
704 unsigned char Service[1]; /* always ASCII, not Unicode */
705 /* STRING NativeFileSystem */
706} __attribute__((packed)) TCONX_RSP_EXT;
707
708
683/* tree connect Flags */ 709/* tree connect Flags */
684#define DISCONNECT_TID 0x0001 710#define DISCONNECT_TID 0x0001
711#define TCON_EXTENDED_SIGNATURES 0x0004
685#define TCON_EXTENDED_SECINFO 0x0008 712#define TCON_EXTENDED_SECINFO 0x0008
713
686/* OptionalSupport bits */ 714/* OptionalSupport bits */
687#define SMB_SUPPORT_SEARCH_BITS 0x0001 /* "must have" directory search bits 715#define SMB_SUPPORT_SEARCH_BITS 0x0001 /* "must have" directory search bits
688 (exclusive searches supported) */ 716 (exclusive searches supported) */
689#define SMB_SHARE_IS_IN_DFS 0x0002 717#define SMB_SHARE_IS_IN_DFS 0x0002
718#define SMB_CSC_MASK 0x000C
719/* CSC flags defined as follows */
720#define SMB_CSC_CACHE_MANUAL_REINT 0x0000
721#define SMB_CSC_CACHE_AUTO_REINT 0x0004
722#define SMB_CSC_CACHE_VDO 0x0008
723#define SMB_CSC_NO_CACHING 0x000C
724
725#define SMB_UNIQUE_FILE_NAME 0x0010
726#define SMB_EXTENDED_SIGNATURES 0x0020
727
728/* services
729 *
730 * A: ie disk
731 * LPT1: ie printer
732 * IPC ie named pipe
733 * COMM
734 * ????? ie any type
735 *
736 */
690 737
691typedef struct smb_com_logoff_andx_req { 738typedef struct smb_com_logoff_andx_req {
692 struct smb_hdr hdr; /* wct = 2 */ 739 struct smb_hdr hdr; /* wct = 2 */
@@ -750,6 +797,17 @@ typedef struct smb_com_findclose_req {
750#define COMM_DEV_TYPE 0x0004 797#define COMM_DEV_TYPE 0x0004
751#define UNKNOWN_TYPE 0xFFFF 798#define UNKNOWN_TYPE 0xFFFF
752 799
800/* Device Type or File Status Flags */
801#define NO_EAS 0x0001
802#define NO_SUBSTREAMS 0x0002
803#define NO_REPARSETAG 0x0004
804/* following flags can apply if pipe */
805#define ICOUNT_MASK 0x00FF
806#define PIPE_READ_MODE 0x0100
807#define NAMED_PIPE_TYPE 0x0400
808#define PIPE_END_POINT 0x0800
809#define BLOCKING_NAMED_PIPE 0x8000
810
753typedef struct smb_com_open_req { /* also handles create */ 811typedef struct smb_com_open_req { /* also handles create */
754 struct smb_hdr hdr; /* wct = 24 */ 812 struct smb_hdr hdr; /* wct = 24 */
755 __u8 AndXCommand; 813 __u8 AndXCommand;
@@ -758,7 +816,7 @@ typedef struct smb_com_open_req { /* also handles create */
758 __u8 Reserved; /* Must Be Zero */ 816 __u8 Reserved; /* Must Be Zero */
759 __le16 NameLength; 817 __le16 NameLength;
760 __le32 OpenFlags; 818 __le32 OpenFlags;
761 __le32 RootDirectoryFid; 819 __u32 RootDirectoryFid;
762 __le32 DesiredAccess; 820 __le32 DesiredAccess;
763 __le64 AllocationSize; 821 __le64 AllocationSize;
764 __le32 FileAttributes; 822 __le32 FileAttributes;
@@ -801,6 +859,32 @@ typedef struct smb_com_open_rsp {
801 __u16 ByteCount; /* bct = 0 */ 859 __u16 ByteCount; /* bct = 0 */
802} __attribute__((packed)) OPEN_RSP; 860} __attribute__((packed)) OPEN_RSP;
803 861
862typedef struct smb_com_open_rsp_ext {
863 struct smb_hdr hdr; /* wct = 42 but meaningless due to MS bug? */
864 __u8 AndXCommand;
865 __u8 AndXReserved;
866 __le16 AndXOffset;
867 __u8 OplockLevel;
868 __u16 Fid;
869 __le32 CreateAction;
870 __le64 CreationTime;
871 __le64 LastAccessTime;
872 __le64 LastWriteTime;
873 __le64 ChangeTime;
874 __le32 FileAttributes;
875 __le64 AllocationSize;
876 __le64 EndOfFile;
877 __le16 FileType;
878 __le16 DeviceState;
879 __u8 DirectoryFlag;
880 __u8 VolumeGUID[16];
881 __u64 FileId; /* note no endian conversion - is opaque UniqueID */
882 __le32 MaximalAccessRights;
883 __le32 GuestMaximalAccessRights;
884 __u16 ByteCount; /* bct = 0 */
885} __attribute__((packed)) OPEN_RSP_EXT;
886
887
804/* format of legacy open request */ 888/* format of legacy open request */
805typedef struct smb_com_openx_req { 889typedef struct smb_com_openx_req {
806 struct smb_hdr hdr; /* wct = 15 */ 890 struct smb_hdr hdr; /* wct = 15 */
@@ -1703,6 +1787,11 @@ typedef struct smb_com_transaction2_fnext_rsp_parms {
1703#define SMB_QUERY_CIFS_UNIX_INFO 0x200 1787#define SMB_QUERY_CIFS_UNIX_INFO 0x200
1704#define SMB_QUERY_POSIX_FS_INFO 0x201 1788#define SMB_QUERY_POSIX_FS_INFO 0x201
1705#define SMB_QUERY_POSIX_WHO_AM_I 0x202 1789#define SMB_QUERY_POSIX_WHO_AM_I 0x202
1790#define SMB_QUERY_FS_PROXY 0x203 /* WAFS enabled. Returns structure
1791 FILE_SYSTEM__UNIX_INFO to tell
1792 whether new NTIOCTL available
1793 (0xACE) for WAN friendly SMB
1794 operations to be carried */
1706#define SMB_QUERY_LABEL_INFO 0x3ea 1795#define SMB_QUERY_LABEL_INFO 0x3ea
1707#define SMB_QUERY_FS_QUOTA_INFO 0x3ee 1796#define SMB_QUERY_FS_QUOTA_INFO 0x3ee
1708#define SMB_QUERY_FS_FULL_SIZE_INFO 0x3ef 1797#define SMB_QUERY_FS_FULL_SIZE_INFO 0x3ef
@@ -1959,7 +2048,8 @@ typedef struct {
1959#define CIFS_UNIX_LARGE_READ_CAP 0x00000040 /* support reads >128K (up 2048#define CIFS_UNIX_LARGE_READ_CAP 0x00000040 /* support reads >128K (up
1960 to 0xFFFF00 */ 2049 to 0xFFFF00 */
1961#define CIFS_UNIX_LARGE_WRITE_CAP 0x00000080 2050#define CIFS_UNIX_LARGE_WRITE_CAP 0x00000080
1962 2051#define CIFS_UNIX_PROXY_CAP 0x00000100 /* Proxy cap: 0xACE ioctl and
2052 QFS PROXY call */
1963#ifdef CONFIG_CIFS_POSIX 2053#ifdef CONFIG_CIFS_POSIX
1964/* Can not set pathnames cap yet until we send new posix create SMB since 2054/* Can not set pathnames cap yet until we send new posix create SMB since
1965 otherwise server can treat such handles opened with older ntcreatex 2055 otherwise server can treat such handles opened with older ntcreatex
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 7e5e0e78cd72..0c83da4a7dab 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -84,6 +84,7 @@ extern __u16 GetNextMid(struct TCP_Server_Info *server);
84extern struct oplock_q_entry *AllocOplockQEntry(struct inode *, u16, 84extern struct oplock_q_entry *AllocOplockQEntry(struct inode *, u16,
85 struct cifsTconInfo *); 85 struct cifsTconInfo *);
86extern void DeleteOplockQEntry(struct oplock_q_entry *); 86extern void DeleteOplockQEntry(struct oplock_q_entry *);
87extern void DeleteTconOplockQEntries(struct cifsTconInfo *);
87extern struct timespec cifs_NTtimeToUnix(u64 utc_nanoseconds_since_1601); 88extern struct timespec cifs_NTtimeToUnix(u64 utc_nanoseconds_since_1601);
88extern u64 cifs_UnixTimeToNT(struct timespec); 89extern u64 cifs_UnixTimeToNT(struct timespec);
89extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time); 90extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time);
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 30bbe448e260..4728fa982a4e 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -165,17 +165,19 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
165 rc = CIFSTCon(0, tcon->ses, tcon->treeName, 165 rc = CIFSTCon(0, tcon->ses, tcon->treeName,
166 tcon, nls_codepage); 166 tcon, nls_codepage);
167 up(&tcon->ses->sesSem); 167 up(&tcon->ses->sesSem);
168 /* tell server which Unix caps we support */
169 if (tcon->ses->capabilities & CAP_UNIX)
170 reset_cifs_unix_caps(0 /* no xid */,
171 tcon,
172 NULL /* we do not know sb */,
173 NULL /* no vol info */);
174 /* BB FIXME add code to check if wsize needs 168 /* BB FIXME add code to check if wsize needs
175 update due to negotiated smb buffer size 169 update due to negotiated smb buffer size
176 shrinking */ 170 shrinking */
177 if (rc == 0) 171 if (rc == 0) {
178 atomic_inc(&tconInfoReconnectCount); 172 atomic_inc(&tconInfoReconnectCount);
173 /* tell server Unix caps we support */
174 if (tcon->ses->capabilities & CAP_UNIX)
175 reset_cifs_unix_caps(
176 0 /* no xid */,
177 tcon,
178 NULL /* we do not know sb */,
179 NULL /* no vol info */);
180 }
179 181
180 cFYI(1, ("reconnect tcon rc = %d", rc)); 182 cFYI(1, ("reconnect tcon rc = %d", rc));
181 /* Removed call to reopen open files here. 183 /* Removed call to reopen open files here.
@@ -310,17 +312,19 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
310 rc = CIFSTCon(0, tcon->ses, tcon->treeName, 312 rc = CIFSTCon(0, tcon->ses, tcon->treeName,
311 tcon, nls_codepage); 313 tcon, nls_codepage);
312 up(&tcon->ses->sesSem); 314 up(&tcon->ses->sesSem);
313 /* tell server which Unix caps we support */
314 if (tcon->ses->capabilities & CAP_UNIX)
315 reset_cifs_unix_caps(0 /* no xid */,
316 tcon,
317 NULL /* do not know sb */,
318 NULL /* no vol info */);
319 /* BB FIXME add code to check if wsize needs 315 /* BB FIXME add code to check if wsize needs
320 update due to negotiated smb buffer size 316 update due to negotiated smb buffer size
321 shrinking */ 317 shrinking */
322 if (rc == 0) 318 if (rc == 0) {
323 atomic_inc(&tconInfoReconnectCount); 319 atomic_inc(&tconInfoReconnectCount);
320 /* tell server Unix caps we support */
321 if (tcon->ses->capabilities & CAP_UNIX)
322 reset_cifs_unix_caps(
323 0 /* no xid */,
324 tcon,
325 NULL /* do not know sb */,
326 NULL /* no vol info */);
327 }
324 328
325 cFYI(1, ("reconnect tcon rc = %d", rc)); 329 cFYI(1, ("reconnect tcon rc = %d", rc));
326 /* Removed call to reopen open files here. 330 /* Removed call to reopen open files here.
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 8dbfa97cd18c..e17106730168 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -3527,6 +3527,7 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3527 FreeXid(xid); 3527 FreeXid(xid);
3528 return 0; 3528 return 0;
3529 } 3529 }
3530 DeleteTconOplockQEntries(cifs_sb->tcon);
3530 tconInfoFree(cifs_sb->tcon); 3531 tconInfoFree(cifs_sb->tcon);
3531 if ((ses) && (ses->server)) { 3532 if ((ses) && (ses->server)) {
3532 /* save off task so we do not refer to ses later */ 3533 /* save off task so we do not refer to ses later */
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index bc673c8c1e6b..e1031b9e2c55 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -161,12 +161,14 @@ static void cifs_unix_info_to_inode(struct inode *inode,
161 spin_unlock(&inode->i_lock); 161 spin_unlock(&inode->i_lock);
162} 162}
163 163
164static const unsigned char *cifs_get_search_path(struct cifsTconInfo *pTcon, 164static const unsigned char *cifs_get_search_path(struct cifs_sb_info *cifs_sb,
165 const char *search_path) 165 const char *search_path)
166{ 166{
167 int tree_len; 167 int tree_len;
168 int path_len; 168 int path_len;
169 int i;
169 char *tmp_path; 170 char *tmp_path;
171 struct cifsTconInfo *pTcon = cifs_sb->tcon;
170 172
171 if (!(pTcon->Flags & SMB_SHARE_IS_IN_DFS)) 173 if (!(pTcon->Flags & SMB_SHARE_IS_IN_DFS))
172 return search_path; 174 return search_path;
@@ -180,6 +182,11 @@ static const unsigned char *cifs_get_search_path(struct cifsTconInfo *pTcon,
180 return search_path; 182 return search_path;
181 183
182 strncpy(tmp_path, pTcon->treeName, tree_len); 184 strncpy(tmp_path, pTcon->treeName, tree_len);
185 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
186 for (i = 0; i < tree_len; i++) {
187 if (tmp_path[i] == '\\')
188 tmp_path[i] = '/';
189 }
183 strncpy(tmp_path+tree_len, search_path, path_len); 190 strncpy(tmp_path+tree_len, search_path, path_len);
184 tmp_path[tree_len+path_len] = 0; 191 tmp_path[tree_len+path_len] = 0;
185 return tmp_path; 192 return tmp_path;
@@ -199,7 +206,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
199 pTcon = cifs_sb->tcon; 206 pTcon = cifs_sb->tcon;
200 cFYI(1, ("Getting info on %s", search_path)); 207 cFYI(1, ("Getting info on %s", search_path));
201 208
202 full_path = cifs_get_search_path(pTcon, search_path); 209 full_path = cifs_get_search_path(cifs_sb, search_path);
203 210
204try_again_CIFSSMBUnixQPathInfo: 211try_again_CIFSSMBUnixQPathInfo:
205 /* could have done a find first instead but this returns more info */ 212 /* could have done a find first instead but this returns more info */
@@ -402,7 +409,7 @@ int cifs_get_inode_info(struct inode **pinode,
402 return -ENOMEM; 409 return -ENOMEM;
403 pfindData = (FILE_ALL_INFO *)buf; 410 pfindData = (FILE_ALL_INFO *)buf;
404 411
405 full_path = cifs_get_search_path(pTcon, search_path); 412 full_path = cifs_get_search_path(cifs_sb, search_path);
406 413
407try_again_CIFSSMBQPathInfo: 414try_again_CIFSSMBQPathInfo:
408 /* could do find first instead but this returns more info */ 415 /* could do find first instead but this returns more info */
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 3612d6c0a0bb..000ac509c98a 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -142,6 +142,24 @@ void DeleteOplockQEntry(struct oplock_q_entry *oplockEntry)
142 kmem_cache_free(cifs_oplock_cachep, oplockEntry); 142 kmem_cache_free(cifs_oplock_cachep, oplockEntry);
143} 143}
144 144
145
146void DeleteTconOplockQEntries(struct cifsTconInfo *tcon)
147{
148 struct oplock_q_entry *temp;
149
150 if (tcon == NULL)
151 return;
152
153 spin_lock(&GlobalMid_Lock);
154 list_for_each_entry(temp, &GlobalOplock_Q, qhead) {
155 if ((temp->tcon) && (temp->tcon == tcon)) {
156 list_del(&temp->qhead);
157 kmem_cache_free(cifs_oplock_cachep, temp);
158 }
159 }
160 spin_unlock(&GlobalMid_Lock);
161}
162
145int 163int
146smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, 164smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
147 unsigned int smb_buf_length, struct sockaddr *sin) 165 unsigned int smb_buf_length, struct sockaddr *sin)