diff options
-rw-r--r-- | fs/cifs/CHANGES | 3 | ||||
-rw-r--r-- | fs/cifs/README | 9 | ||||
-rw-r--r-- | fs/cifs/cifs_dfs_ref.c | 2 | ||||
-rw-r--r-- | fs/cifs/cifsacl.c | 14 | ||||
-rw-r--r-- | fs/cifs/cifsacl.h | 1 | ||||
-rw-r--r-- | fs/cifs/cifsfs.h | 2 | ||||
-rw-r--r-- | fs/cifs/cifspdu.h | 121 | ||||
-rw-r--r-- | fs/cifs/cifsproto.h | 1 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 32 | ||||
-rw-r--r-- | fs/cifs/connect.c | 1 | ||||
-rw-r--r-- | fs/cifs/inode.c | 15 | ||||
-rw-r--r-- | fs/cifs/transport.c | 18 |
12 files changed, 176 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). | |||
8 | Add ability to modify cifs acls for handling chmod (when mounted with | 8 | Add ability to modify cifs acls for handling chmod (when mounted with |
9 | cifsacl flag). Fix prefixpath path separator so we can handle mounts | 9 | cifsacl flag). Fix prefixpath path separator so we can handle mounts |
10 | with prefixpaths longer than one directory (one path component) when | 10 | with prefixpaths longer than one directory (one path component) when |
11 | mounted to Windows servers. | 11 | mounted to Windows servers. Fix slow file open when cifsacl |
12 | enabled. | ||
12 | 13 | ||
13 | Version 1.51 | 14 | Version 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. | |||
3 | It was designed to comply with the SNIA CIFS Technical Reference (which | 3 | It was designed to comply with the SNIA CIFS Technical Reference (which |
4 | supersedes the 1992 X/Open SMB Standard) as well as to perform best practice | 4 | supersedes the 1992 X/Open SMB Standard) as well as to perform best practice |
5 | practical interoperability with Windows 2000, Windows XP, Samba and equivalent | 5 | practical interoperability with Windows 2000, Windows XP, Samba and equivalent |
6 | servers. | 6 | servers. This code was developed in participation with the Protocol Freedom |
7 | Information Foundation. | ||
8 | |||
9 | Please see | ||
10 | http://protocolfreedom.org/ and | ||
11 | http://samba.org/samba/PFIF/ | ||
12 | for more details. | ||
13 | |||
7 | 14 | ||
8 | For questions or bug reports please contact: | 15 | For 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 | ||
26 | LIST_HEAD(cifs_dfs_automount_list); | 26 | static 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 */ |
518 | static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, | 518 | static 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) | |||
692 | int mode_to_acl(struct inode *inode, const char *path, __u64 nmode) | 692 | int 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 | ||
63 | extern const struct inode_operations cifs_file_inode_ops; | 63 | extern const struct inode_operations cifs_file_inode_ops; |
64 | extern const struct inode_operations cifs_symlink_inode_ops; | 64 | extern const struct inode_operations cifs_symlink_inode_ops; |
65 | extern struct list_head cifs_dfs_automount_list; | ||
66 | extern struct inode_operations cifs_dfs_referral_inode_operations; | 65 | extern 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 */ |
71 | extern const struct file_operations cifs_file_ops; | 69 | extern const struct file_operations cifs_file_ops; |
72 | extern const struct file_operations cifs_file_direct_ops; /* if directio mnt */ | 70 | extern 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..9f49c2f3582c 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 | ||
471 | typedef struct negotiate_rsp { | 484 | typedef 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 | ||
525 | typedef union smb_com_session_setup_andx { | 539 | typedef 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 | ||
670 | typedef struct smb_com_tconx_rsp { | 684 | typedef 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 | ||
695 | typedef 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 | ||
691 | typedef struct smb_com_logoff_andx_req { | 738 | typedef 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 | |||
753 | typedef struct smb_com_open_req { /* also handles create */ | 811 | typedef 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 | ||
862 | typedef 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 */ |
805 | typedef struct smb_com_openx_req { | 889 | typedef struct smb_com_openx_req { |
806 | struct smb_hdr hdr; /* wct = 15 */ | 890 | struct smb_hdr hdr; /* wct = 15 */ |
@@ -1703,6 +1787,12 @@ 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_REQUEST_TRANSPORT_ENCRYPTION 0x203 | ||
1791 | #define SMB_QUERY_FS_PROXY 0x204 /* WAFS enabled. Returns structure | ||
1792 | FILE_SYSTEM__UNIX_INFO to tell | ||
1793 | whether new NTIOCTL available | ||
1794 | (0xACE) for WAN friendly SMB | ||
1795 | operations to be carried */ | ||
1706 | #define SMB_QUERY_LABEL_INFO 0x3ea | 1796 | #define SMB_QUERY_LABEL_INFO 0x3ea |
1707 | #define SMB_QUERY_FS_QUOTA_INFO 0x3ee | 1797 | #define SMB_QUERY_FS_QUOTA_INFO 0x3ee |
1708 | #define SMB_QUERY_FS_FULL_SIZE_INFO 0x3ef | 1798 | #define SMB_QUERY_FS_FULL_SIZE_INFO 0x3ef |
@@ -1959,7 +2049,10 @@ typedef struct { | |||
1959 | #define CIFS_UNIX_LARGE_READ_CAP 0x00000040 /* support reads >128K (up | 2049 | #define CIFS_UNIX_LARGE_READ_CAP 0x00000040 /* support reads >128K (up |
1960 | to 0xFFFF00 */ | 2050 | to 0xFFFF00 */ |
1961 | #define CIFS_UNIX_LARGE_WRITE_CAP 0x00000080 | 2051 | #define CIFS_UNIX_LARGE_WRITE_CAP 0x00000080 |
1962 | 2052 | #define CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP 0x00000100 /* can do SPNEGO crypt */ | |
2053 | #define CIFS_UNIX_TRANPSORT_ENCRYPTION_MANDATORY_CAP 0x00000200 /* must do */ | ||
2054 | #define CIFS_UNIX_PROXY_CAP 0x00000400 /* Proxy cap: 0xACE ioctl and | ||
2055 | QFS PROXY call */ | ||
1963 | #ifdef CONFIG_CIFS_POSIX | 2056 | #ifdef CONFIG_CIFS_POSIX |
1964 | /* Can not set pathnames cap yet until we send new posix create SMB since | 2057 | /* 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 | 2058 | 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); | |||
84 | extern struct oplock_q_entry *AllocOplockQEntry(struct inode *, u16, | 84 | extern struct oplock_q_entry *AllocOplockQEntry(struct inode *, u16, |
85 | struct cifsTconInfo *); | 85 | struct cifsTconInfo *); |
86 | extern void DeleteOplockQEntry(struct oplock_q_entry *); | 86 | extern void DeleteOplockQEntry(struct oplock_q_entry *); |
87 | extern void DeleteTconOplockQEntries(struct cifsTconInfo *); | ||
87 | extern struct timespec cifs_NTtimeToUnix(u64 utc_nanoseconds_since_1601); | 88 | extern struct timespec cifs_NTtimeToUnix(u64 utc_nanoseconds_since_1601); |
88 | extern u64 cifs_UnixTimeToNT(struct timespec); | 89 | extern u64 cifs_UnixTimeToNT(struct timespec); |
89 | extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time); | 90 | extern __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 | ||
164 | static const unsigned char *cifs_get_search_path(struct cifsTconInfo *pTcon, | 164 | static 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 | ||
204 | try_again_CIFSSMBUnixQPathInfo: | 211 | try_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 | ||
407 | try_again_CIFSSMBQPathInfo: | 414 | try_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 | |||
146 | void 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 | |||
145 | int | 163 | int |
146 | smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, | 164 | smb_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) |