Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6:
[CIFS] Fix typo in previous commit
[CIFS] Fix define for new proxy cap to match documentation
[CIFS] Fix UNC path prefix on QueryUnixPathInfo to have correct slash
[CIFS] Reserve new proxy cap for WAFS
[CIFS] Add various missing flags and defintions
[CIFS] make cifs_dfs_automount_list_static
[CIFS] Fix oops when slow oplock process races with unmount
[CIFS] Fix acl length when very short ACL being modified by chmod
[CIFS] Fix looping on reconnect to Samba when unexpected tree connect fail on reconnect
[CIFS] minor update to change log

+176 -43
+2 -1
fs/cifs/CHANGES
··· 8 8 Add ability to modify cifs acls for handling chmod (when mounted with 9 9 cifsacl flag). Fix prefixpath path separator so we can handle mounts 10 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 14 Version 1.51 14 15 ------------
+8 -1
fs/cifs/README
··· 3 3 It was designed to comply with the SNIA CIFS Technical Reference (which 4 4 supersedes the 1992 X/Open SMB Standard) as well as to perform best practice 5 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 15 For questions or bug reports please contact: 9 16 sfrench@samba.org (sfrench@us.ibm.com)
+1 -1
fs/cifs/cifs_dfs_ref.c
··· 23 23 #include "dns_resolve.h" 24 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 29 * DFS functions
+8 -6
fs/cifs/cifsacl.c
··· 516 516 517 517 /* Convert permission bits from mode to equivalent CIFS ACL */ 518 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 521 int rc = 0; 522 522 __u32 dacloffset; ··· 692 692 int mode_to_acl(struct inode *inode, const char *path, __u64 nmode) 693 693 { 694 694 int rc = 0; 695 - __u32 acllen = 0; 695 + __u32 secdesclen = 0; 696 696 struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */ 697 697 struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */ 698 698 699 699 cFYI(DBG2, ("set ACL from mode for %s", path)); 700 700 701 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 704 /* Add three ACEs for owner, group, everyone getting rid of 705 705 other ACEs as chmod disables ACEs and set the security descriptor */ ··· 709 709 set security descriptor request security descriptor 710 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 715 if (!pnntsd) { 714 716 cERROR(1, ("Unable to allocate security descriptor")); 715 717 kfree(pntsd); 716 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 723 cFYI(DBG2, ("build_sec_desc rc: %d", rc)); 722 724 723 725 if (!rc) { 724 726 /* Set the security descriptor */ 725 - rc = set_cifs_acl(pnntsd, acllen, inode, path); 727 + rc = set_cifs_acl(pnntsd, secdesclen, inode, path); 726 728 cFYI(DBG2, ("set_cifs_acl rc: %d", rc)); 727 729 } 728 730
+1
fs/cifs/cifsacl.h
··· 27 27 #define NUM_SUBAUTHS 5 /* number of sub authority fields */ 28 28 #define NUM_WK_SIDS 7 /* number of well known sids */ 29 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 32 #define READ_BIT 0x4 32 33 #define WRITE_BIT 0x2
-2
fs/cifs/cifsfs.h
··· 62 62 63 63 extern const struct inode_operations cifs_file_inode_ops; 64 64 extern const struct inode_operations cifs_symlink_inode_ops; 65 - extern struct list_head cifs_dfs_automount_list; 66 65 extern struct inode_operations cifs_dfs_referral_inode_operations; 67 - 68 66 69 67 70 68 /* Functions related to files and directories */
+107 -14
fs/cifs/cifspdu.h
··· 1 1 /* 2 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 5 * Author(s): Steve French (sfrench@us.ibm.com) 6 6 * 7 7 * This library is free software; you can redistribute it and/or modify ··· 163 163 path names in response */ 164 164 #define SMBFLG2_KNOWS_EAS cpu_to_le16(2) 165 165 #define SMBFLG2_SECURITY_SIGNATURE cpu_to_le16(4) 166 + #define SMBFLG2_COMPRESSED (8) 167 + #define SMBFLG2_SECURITY_SIGNATURE_REQUIRED (0x10) 166 168 #define SMBFLG2_IS_LONG_NAME cpu_to_le16(0x40) 169 + #define SMBFLG2_REPARSE_PATH (0x400) 167 170 #define SMBFLG2_EXT_SEC cpu_to_le16(0x800) 168 171 #define SMBFLG2_DFS cpu_to_le16(0x1000) 169 172 #define SMBFLG2_PAGING_IO cpu_to_le16(0x2000) ··· 308 305 #define FILE_SHARE_DELETE 0x00000004 309 306 #define FILE_SHARE_ALL 0x00000007 310 307 311 - /* CreateDisposition flags */ 308 + /* CreateDisposition flags, similar to CreateAction as well */ 312 309 #define FILE_SUPERSEDE 0x00000000 313 310 #define FILE_OPEN 0x00000001 314 311 #define FILE_CREATE 0x00000002 ··· 320 317 #define CREATE_NOT_FILE 0x00000001 /* if set must not be file */ 321 318 #define CREATE_WRITE_THROUGH 0x00000002 322 319 #define CREATE_SEQUENTIAL 0x00000004 323 - #define CREATE_SYNC_ALERT 0x00000010 324 - #define CREATE_ASYNC_ALERT 0x00000020 320 + #define CREATE_NO_BUFFER 0x00000008 /* should not buffer on srv */ 321 + #define CREATE_SYNC_ALERT 0x00000010 /* MBZ */ 322 + #define CREATE_ASYNC_ALERT 0x00000020 /* MBZ */ 325 323 #define CREATE_NOT_DIR 0x00000040 /* if set must not be directory */ 324 + #define CREATE_TREE_CONNECTION 0x00000080 /* should be zero */ 325 + #define CREATE_COMPLETE_IF_OPLK 0x00000100 /* should be zero */ 326 326 #define CREATE_NO_EA_KNOWLEDGE 0x00000200 327 - #define CREATE_EIGHT_DOT_THREE 0x00000400 327 + #define CREATE_EIGHT_DOT_THREE 0x00000400 /* doc says this is obsolete 328 + open for recovery flag - should 329 + be zero */ 328 330 #define CREATE_RANDOM_ACCESS 0x00000800 329 331 #define CREATE_DELETE_ON_CLOSE 0x00001000 330 332 #define CREATE_OPEN_BY_ID 0x00002000 333 + #define CREATE_OPEN_BACKUP_INTN 0x00004000 334 + #define CREATE_NO_COMPRESSION 0x00008000 335 + #define CREATE_RESERVE_OPFILTER 0x00100000 /* should be zero */ 331 336 #define OPEN_REPARSE_POINT 0x00200000 337 + #define OPEN_NO_RECALL 0x00400000 338 + #define OPEN_FREE_SPACE_QUERY 0x00800000 /* should be zero */ 332 339 #define CREATE_OPTIONS_MASK 0x007FFFFF 333 340 #define CREATE_OPTION_SPECIAL 0x20000000 /* system. NB not sent over wire */ 334 341 ··· 483 470 484 471 typedef struct negotiate_rsp { 485 472 struct smb_hdr hdr; /* wct = 17 */ 486 - __le16 DialectIndex; 473 + __le16 DialectIndex; /* 0xFFFF = no dialect acceptable */ 487 474 __u8 SecurityMode; 488 475 __le16 MaxMpxCount; 489 476 __le16 MaxNumberVcs; ··· 529 516 #define CAP_INFOLEVEL_PASSTHRU 0x00002000 530 517 #define CAP_LARGE_READ_X 0x00004000 531 518 #define CAP_LARGE_WRITE_X 0x00008000 519 + #define CAP_LWIO 0x00010000 /* support fctl_srv_req_resume_key */ 532 520 #define CAP_UNIX 0x00800000 533 - #define CAP_RESERVED 0x02000000 534 - #define CAP_BULK_TRANSFER 0x20000000 535 - #define CAP_COMPRESSED_DATA 0x40000000 521 + #define CAP_COMPRESSED_DATA 0x02000000 522 + #define CAP_DYNAMIC_REAUTH 0x20000000 523 + #define CAP_PERSISTENT_HANDLES 0x40000000 536 524 #define CAP_EXTENDED_SECURITY 0x80000000 537 525 538 526 typedef union smb_com_session_setup_andx { ··· 682 668 } __attribute__((packed)) TCONX_REQ; 683 669 684 670 typedef struct smb_com_tconx_rsp { 685 - struct smb_hdr hdr; /* wct = 3 note that Win2000 has sent wct = 7 686 - in some cases on responses. Four unspecified 687 - words followed OptionalSupport */ 671 + struct smb_hdr hdr; /* wct = 3 , not extended response */ 688 672 __u8 AndXCommand; 689 673 __u8 AndXReserved; 690 674 __le16 AndXOffset; ··· 692 680 /* STRING NativeFileSystem */ 693 681 } __attribute__((packed)) TCONX_RSP; 694 682 683 + typedef struct smb_com_tconx_rsp_ext { 684 + struct smb_hdr hdr; /* wct = 7, extended response */ 685 + __u8 AndXCommand; 686 + __u8 AndXReserved; 687 + __le16 AndXOffset; 688 + __le16 OptionalSupport; /* see below */ 689 + __le32 MaximalShareAccessRights; 690 + __le32 GuestMaximalShareAccessRights; 691 + __u16 ByteCount; 692 + unsigned char Service[1]; /* always ASCII, not Unicode */ 693 + /* STRING NativeFileSystem */ 694 + } __attribute__((packed)) TCONX_RSP_EXT; 695 + 696 + 695 697 /* tree connect Flags */ 696 698 #define DISCONNECT_TID 0x0001 699 + #define TCON_EXTENDED_SIGNATURES 0x0004 697 700 #define TCON_EXTENDED_SECINFO 0x0008 701 + 698 702 /* OptionalSupport bits */ 699 703 #define SMB_SUPPORT_SEARCH_BITS 0x0001 /* "must have" directory search bits 700 704 (exclusive searches supported) */ 701 705 #define SMB_SHARE_IS_IN_DFS 0x0002 706 + #define SMB_CSC_MASK 0x000C 707 + /* CSC flags defined as follows */ 708 + #define SMB_CSC_CACHE_MANUAL_REINT 0x0000 709 + #define SMB_CSC_CACHE_AUTO_REINT 0x0004 710 + #define SMB_CSC_CACHE_VDO 0x0008 711 + #define SMB_CSC_NO_CACHING 0x000C 712 + 713 + #define SMB_UNIQUE_FILE_NAME 0x0010 714 + #define SMB_EXTENDED_SIGNATURES 0x0020 715 + 716 + /* services 717 + * 718 + * A: ie disk 719 + * LPT1: ie printer 720 + * IPC ie named pipe 721 + * COMM 722 + * ????? ie any type 723 + * 724 + */ 702 725 703 726 typedef struct smb_com_logoff_andx_req { 704 727 struct smb_hdr hdr; /* wct = 2 */ ··· 797 750 #define COMM_DEV_TYPE 0x0004 798 751 #define UNKNOWN_TYPE 0xFFFF 799 752 753 + /* Device Type or File Status Flags */ 754 + #define NO_EAS 0x0001 755 + #define NO_SUBSTREAMS 0x0002 756 + #define NO_REPARSETAG 0x0004 757 + /* following flags can apply if pipe */ 758 + #define ICOUNT_MASK 0x00FF 759 + #define PIPE_READ_MODE 0x0100 760 + #define NAMED_PIPE_TYPE 0x0400 761 + #define PIPE_END_POINT 0x0800 762 + #define BLOCKING_NAMED_PIPE 0x8000 763 + 800 764 typedef struct smb_com_open_req { /* also handles create */ 801 765 struct smb_hdr hdr; /* wct = 24 */ 802 766 __u8 AndXCommand; ··· 816 758 __u8 Reserved; /* Must Be Zero */ 817 759 __le16 NameLength; 818 760 __le32 OpenFlags; 819 - __le32 RootDirectoryFid; 761 + __u32 RootDirectoryFid; 820 762 __le32 DesiredAccess; 821 763 __le64 AllocationSize; 822 764 __le32 FileAttributes; ··· 858 800 __u8 DirectoryFlag; 859 801 __u16 ByteCount; /* bct = 0 */ 860 802 } __attribute__((packed)) OPEN_RSP; 803 + 804 + typedef struct smb_com_open_rsp_ext { 805 + struct smb_hdr hdr; /* wct = 42 but meaningless due to MS bug? */ 806 + __u8 AndXCommand; 807 + __u8 AndXReserved; 808 + __le16 AndXOffset; 809 + __u8 OplockLevel; 810 + __u16 Fid; 811 + __le32 CreateAction; 812 + __le64 CreationTime; 813 + __le64 LastAccessTime; 814 + __le64 LastWriteTime; 815 + __le64 ChangeTime; 816 + __le32 FileAttributes; 817 + __le64 AllocationSize; 818 + __le64 EndOfFile; 819 + __le16 FileType; 820 + __le16 DeviceState; 821 + __u8 DirectoryFlag; 822 + __u8 VolumeGUID[16]; 823 + __u64 FileId; /* note no endian conversion - is opaque UniqueID */ 824 + __le32 MaximalAccessRights; 825 + __le32 GuestMaximalAccessRights; 826 + __u16 ByteCount; /* bct = 0 */ 827 + } __attribute__((packed)) OPEN_RSP_EXT; 828 + 861 829 862 830 /* format of legacy open request */ 863 831 typedef struct smb_com_openx_req { ··· 1787 1703 #define SMB_QUERY_CIFS_UNIX_INFO 0x200 1788 1704 #define SMB_QUERY_POSIX_FS_INFO 0x201 1789 1705 #define SMB_QUERY_POSIX_WHO_AM_I 0x202 1706 + #define SMB_REQUEST_TRANSPORT_ENCRYPTION 0x203 1707 + #define SMB_QUERY_FS_PROXY 0x204 /* WAFS enabled. Returns structure 1708 + FILE_SYSTEM__UNIX_INFO to tell 1709 + whether new NTIOCTL available 1710 + (0xACE) for WAN friendly SMB 1711 + operations to be carried */ 1790 1712 #define SMB_QUERY_LABEL_INFO 0x3ea 1791 1713 #define SMB_QUERY_FS_QUOTA_INFO 0x3ee 1792 1714 #define SMB_QUERY_FS_FULL_SIZE_INFO 0x3ef ··· 2049 1959 #define CIFS_UNIX_LARGE_READ_CAP 0x00000040 /* support reads >128K (up 2050 1960 to 0xFFFF00 */ 2051 1961 #define CIFS_UNIX_LARGE_WRITE_CAP 0x00000080 2052 - 1962 + #define CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP 0x00000100 /* can do SPNEGO crypt */ 1963 + #define CIFS_UNIX_TRANPSORT_ENCRYPTION_MANDATORY_CAP 0x00000200 /* must do */ 1964 + #define CIFS_UNIX_PROXY_CAP 0x00000400 /* Proxy cap: 0xACE ioctl and 1965 + QFS PROXY call */ 2053 1966 #ifdef CONFIG_CIFS_POSIX 2054 1967 /* Can not set pathnames cap yet until we send new posix create SMB since 2055 1968 otherwise server can treat such handles opened with older ntcreatex
+1
fs/cifs/cifsproto.h
··· 84 84 extern struct oplock_q_entry *AllocOplockQEntry(struct inode *, u16, 85 85 struct cifsTconInfo *); 86 86 extern void DeleteOplockQEntry(struct oplock_q_entry *); 87 + extern void DeleteTconOplockQEntries(struct cifsTconInfo *); 87 88 extern struct timespec cifs_NTtimeToUnix(u64 utc_nanoseconds_since_1601); 88 89 extern u64 cifs_UnixTimeToNT(struct timespec); 89 90 extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time);
+18 -14
fs/cifs/cifssmb.c
··· 165 165 rc = CIFSTCon(0, tcon->ses, tcon->treeName, 166 166 tcon, nls_codepage); 167 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 168 /* BB FIXME add code to check if wsize needs 175 169 update due to negotiated smb buffer size 176 170 shrinking */ 177 - if (rc == 0) 171 + if (rc == 0) { 178 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 182 cFYI(1, ("reconnect tcon rc = %d", rc)); 181 183 /* Removed call to reopen open files here. ··· 312 310 rc = CIFSTCon(0, tcon->ses, tcon->treeName, 313 311 tcon, nls_codepage); 314 312 up(&tcon->ses->sesSem); 315 - /* tell server which Unix caps we support */ 316 - if (tcon->ses->capabilities & CAP_UNIX) 317 - reset_cifs_unix_caps(0 /* no xid */, 318 - tcon, 319 - NULL /* do not know sb */, 320 - NULL /* no vol info */); 321 313 /* BB FIXME add code to check if wsize needs 322 314 update due to negotiated smb buffer size 323 315 shrinking */ 324 - if (rc == 0) 316 + if (rc == 0) { 325 317 atomic_inc(&tconInfoReconnectCount); 318 + /* tell server Unix caps we support */ 319 + if (tcon->ses->capabilities & CAP_UNIX) 320 + reset_cifs_unix_caps( 321 + 0 /* no xid */, 322 + tcon, 323 + NULL /* do not know sb */, 324 + NULL /* no vol info */); 325 + } 326 326 327 327 cFYI(1, ("reconnect tcon rc = %d", rc)); 328 328 /* Removed call to reopen open files here.
+1
fs/cifs/connect.c
··· 3527 3527 FreeXid(xid); 3528 3528 return 0; 3529 3529 } 3530 + DeleteTconOplockQEntries(cifs_sb->tcon); 3530 3531 tconInfoFree(cifs_sb->tcon); 3531 3532 if ((ses) && (ses->server)) { 3532 3533 /* save off task so we do not refer to ses later */
+11 -4
fs/cifs/inode.c
··· 161 161 spin_unlock(&inode->i_lock); 162 162 } 163 163 164 - static const unsigned char *cifs_get_search_path(struct cifsTconInfo *pTcon, 165 - const char *search_path) 164 + static const unsigned char *cifs_get_search_path(struct cifs_sb_info *cifs_sb, 165 + const char *search_path) 166 166 { 167 167 int tree_len; 168 168 int path_len; 169 + int i; 169 170 char *tmp_path; 171 + struct cifsTconInfo *pTcon = cifs_sb->tcon; 170 172 171 173 if (!(pTcon->Flags & SMB_SHARE_IS_IN_DFS)) 172 174 return search_path; ··· 182 180 return search_path; 183 181 184 182 strncpy(tmp_path, pTcon->treeName, tree_len); 183 + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) 184 + for (i = 0; i < tree_len; i++) { 185 + if (tmp_path[i] == '\\') 186 + tmp_path[i] = '/'; 187 + } 185 188 strncpy(tmp_path+tree_len, search_path, path_len); 186 189 tmp_path[tree_len+path_len] = 0; 187 190 return tmp_path; ··· 206 199 pTcon = cifs_sb->tcon; 207 200 cFYI(1, ("Getting info on %s", search_path)); 208 201 209 - full_path = cifs_get_search_path(pTcon, search_path); 202 + full_path = cifs_get_search_path(cifs_sb, search_path); 210 203 211 204 try_again_CIFSSMBUnixQPathInfo: 212 205 /* could have done a find first instead but this returns more info */ ··· 409 402 return -ENOMEM; 410 403 pfindData = (FILE_ALL_INFO *)buf; 411 404 412 - full_path = cifs_get_search_path(pTcon, search_path); 405 + full_path = cifs_get_search_path(cifs_sb, search_path); 413 406 414 407 try_again_CIFSSMBQPathInfo: 415 408 /* could do find first instead but this returns more info */
+18
fs/cifs/transport.c
··· 142 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 163 int 146 164 smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, 147 165 unsigned int smb_buf_length, struct sockaddr *sin)