aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2010-10-07 23:42:03 -0400
committerSteve French <sfrench@us.ibm.com>2010-10-07 23:42:03 -0400
commit6ea75952d7c671ea8b0d7b66f82afcafbb5d20c2 (patch)
tree66cf5e73830d2730866f7e6bf6cf93f0684c5b99 /fs/cifs
parent6b0cd00bc396daf5c2dcf17a8d82055335341f46 (diff)
parentd2445556137c38ae15d3191174bfd235630ed7cd (diff)
Merge branch 'for-next'
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/README5
-rw-r--r--fs/cifs/cifs_debug.h2
-rw-r--r--fs/cifs/cifs_dfs_ref.c21
-rw-r--r--fs/cifs/cifs_fs_sb.h12
-rw-r--r--fs/cifs/cifsacl.c46
-rw-r--r--fs/cifs/cifsencrypt.c146
-rw-r--r--fs/cifs/cifsfs.c61
-rw-r--r--fs/cifs/cifsfs.h2
-rw-r--r--fs/cifs/cifsglob.h67
-rw-r--r--fs/cifs/cifspdu.h1
-rw-r--r--fs/cifs/cifsproto.h17
-rw-r--r--fs/cifs/cifssmb.c16
-rw-r--r--fs/cifs/cn_cifs.h37
-rw-r--r--fs/cifs/connect.c450
-rw-r--r--fs/cifs/dir.c103
-rw-r--r--fs/cifs/file.c158
-rw-r--r--fs/cifs/fscache.c13
-rw-r--r--fs/cifs/inode.c229
-rw-r--r--fs/cifs/ioctl.c17
-rw-r--r--fs/cifs/link.c372
-rw-r--r--fs/cifs/misc.c2
-rw-r--r--fs/cifs/ntlmssp.h15
-rw-r--r--fs/cifs/readdir.c54
-rw-r--r--fs/cifs/sess.c136
-rw-r--r--fs/cifs/transport.c6
-rw-r--r--fs/cifs/xattr.c60
26 files changed, 1614 insertions, 434 deletions
diff --git a/fs/cifs/README b/fs/cifs/README
index 7099a526f775..ee68d1036544 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -527,6 +527,11 @@ A partial list of the supported mount options follows:
527 SFU does). In the future the bottom 9 bits of the 527 SFU does). In the future the bottom 9 bits of the
528 mode also will be emulated using queries of the security 528 mode also will be emulated using queries of the security
529 descriptor (ACL). 529 descriptor (ACL).
530 mfsymlinks Enable support for Minshall+French symlinks
531 (see http://wiki.samba.org/index.php/UNIX_Extensions#Minshall.2BFrench_symlinks)
532 This option is ignored when specified together with the
533 'sfu' option. Minshall+French symlinks are used even if
534 the server supports the CIFS Unix Extensions.
530 sign Must use packet signing (helps avoid unwanted data modification 535 sign Must use packet signing (helps avoid unwanted data modification
531 by intermediate systems in the route). Note that signing 536 by intermediate systems in the route). Note that signing
532 does not work with lanman or plaintext authentication. 537 does not work with lanman or plaintext authentication.
diff --git a/fs/cifs/cifs_debug.h b/fs/cifs/cifs_debug.h
index aa316891ac0c..8942b28cf807 100644
--- a/fs/cifs/cifs_debug.h
+++ b/fs/cifs/cifs_debug.h
@@ -34,7 +34,7 @@ void cifs_dump_mids(struct TCP_Server_Info *);
34extern int traceSMB; /* flag which enables the function below */ 34extern int traceSMB; /* flag which enables the function below */
35void dump_smb(struct smb_hdr *, int); 35void dump_smb(struct smb_hdr *, int);
36#define CIFS_INFO 0x01 36#define CIFS_INFO 0x01
37#define CIFS_RC 0x02 37#define CIFS_RC 0x02
38#define CIFS_TIMER 0x04 38#define CIFS_TIMER 0x04
39 39
40/* 40/*
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
index d6ced7aa23cf..f4aab6f01174 100644
--- a/fs/cifs/cifs_dfs_ref.c
+++ b/fs/cifs/cifs_dfs_ref.c
@@ -306,6 +306,7 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
306 int xid, i; 306 int xid, i;
307 int rc = 0; 307 int rc = 0;
308 struct vfsmount *mnt = ERR_PTR(-ENOENT); 308 struct vfsmount *mnt = ERR_PTR(-ENOENT);
309 struct tcon_link *tlink;
309 310
310 cFYI(1, "in %s", __func__); 311 cFYI(1, "in %s", __func__);
311 BUG_ON(IS_ROOT(dentry)); 312 BUG_ON(IS_ROOT(dentry));
@@ -315,14 +316,6 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
315 dput(nd->path.dentry); 316 dput(nd->path.dentry);
316 nd->path.dentry = dget(dentry); 317 nd->path.dentry = dget(dentry);
317 318
318 cifs_sb = CIFS_SB(dentry->d_inode->i_sb);
319 ses = cifs_sb->tcon->ses;
320
321 if (!ses) {
322 rc = -EINVAL;
323 goto out_err;
324 }
325
326 /* 319 /*
327 * The MSDFS spec states that paths in DFS referral requests and 320 * The MSDFS spec states that paths in DFS referral requests and
328 * responses must be prefixed by a single '\' character instead of 321 * responses must be prefixed by a single '\' character instead of
@@ -335,10 +328,20 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
335 goto out_err; 328 goto out_err;
336 } 329 }
337 330
338 rc = get_dfs_path(xid, ses , full_path + 1, cifs_sb->local_nls, 331 cifs_sb = CIFS_SB(dentry->d_inode->i_sb);
332 tlink = cifs_sb_tlink(cifs_sb);
333 if (IS_ERR(tlink)) {
334 rc = PTR_ERR(tlink);
335 goto out_err;
336 }
337 ses = tlink_tcon(tlink)->ses;
338
339 rc = get_dfs_path(xid, ses, full_path + 1, cifs_sb->local_nls,
339 &num_referrals, &referrals, 340 &num_referrals, &referrals,
340 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 341 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
341 342
343 cifs_put_tlink(tlink);
344
342 for (i = 0; i < num_referrals; i++) { 345 for (i = 0; i < num_referrals; i++) {
343 int len; 346 int len;
344 dump_referral(referrals+i); 347 dump_referral(referrals+i);
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index 9e771450c3b8..586ee3d527d2 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -15,6 +15,8 @@
15 * the GNU Lesser General Public License for more details. 15 * the GNU Lesser General Public License for more details.
16 * 16 *
17 */ 17 */
18#include <linux/radix-tree.h>
19
18#ifndef _CIFS_FS_SB_H 20#ifndef _CIFS_FS_SB_H
19#define _CIFS_FS_SB_H 21#define _CIFS_FS_SB_H
20 22
@@ -36,10 +38,13 @@
36#define CIFS_MOUNT_NOPOSIXBRL 0x2000 /* mandatory not posix byte range lock */ 38#define CIFS_MOUNT_NOPOSIXBRL 0x2000 /* mandatory not posix byte range lock */
37#define CIFS_MOUNT_NOSSYNC 0x4000 /* don't do slow SMBflush on every sync*/ 39#define CIFS_MOUNT_NOSSYNC 0x4000 /* don't do slow SMBflush on every sync*/
38#define CIFS_MOUNT_FSCACHE 0x8000 /* local caching enabled */ 40#define CIFS_MOUNT_FSCACHE 0x8000 /* local caching enabled */
41#define CIFS_MOUNT_MF_SYMLINKS 0x10000 /* Minshall+French Symlinks enabled */
42#define CIFS_MOUNT_MULTIUSER 0x20000 /* multiuser mount */
39 43
40struct cifs_sb_info { 44struct cifs_sb_info {
41 struct cifsTconInfo *tcon; /* primary mount */ 45 struct radix_tree_root tlink_tree;
42 struct list_head nested_tcon_q; 46#define CIFS_TLINK_MASTER_TAG 0 /* is "master" (mount) tcon */
47 spinlock_t tlink_tree_lock;
43 struct nls_table *local_nls; 48 struct nls_table *local_nls;
44 unsigned int rsize; 49 unsigned int rsize;
45 unsigned int wsize; 50 unsigned int wsize;
@@ -47,12 +52,13 @@ struct cifs_sb_info {
47 gid_t mnt_gid; 52 gid_t mnt_gid;
48 mode_t mnt_file_mode; 53 mode_t mnt_file_mode;
49 mode_t mnt_dir_mode; 54 mode_t mnt_dir_mode;
50 int mnt_cifs_flags; 55 unsigned int mnt_cifs_flags;
51 int prepathlen; 56 int prepathlen;
52 char *prepath; /* relative path under the share to mount to */ 57 char *prepath; /* relative path under the share to mount to */
53#ifdef CONFIG_CIFS_DFS_UPCALL 58#ifdef CONFIG_CIFS_DFS_UPCALL
54 char *mountdata; /* mount options received at mount time */ 59 char *mountdata; /* mount options received at mount time */
55#endif 60#endif
56 struct backing_dev_info bdi; 61 struct backing_dev_info bdi;
62 struct delayed_work prune_tlinks;
57}; 63};
58#endif /* _CIFS_FS_SB_H */ 64#endif /* _CIFS_FS_SB_H */
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index 85d7cf7ff2c8..c9b4792ae825 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -557,11 +557,16 @@ static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
557{ 557{
558 struct cifs_ntsd *pntsd = NULL; 558 struct cifs_ntsd *pntsd = NULL;
559 int xid, rc; 559 int xid, rc;
560 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
561
562 if (IS_ERR(tlink))
563 return NULL;
560 564
561 xid = GetXid(); 565 xid = GetXid();
562 rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen); 566 rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), fid, &pntsd, pacllen);
563 FreeXid(xid); 567 FreeXid(xid);
564 568
569 cifs_put_tlink(tlink);
565 570
566 cFYI(1, "GetCIFSACL rc = %d ACL len %d", rc, *pacllen); 571 cFYI(1, "GetCIFSACL rc = %d ACL len %d", rc, *pacllen);
567 return pntsd; 572 return pntsd;
@@ -574,10 +579,16 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
574 int oplock = 0; 579 int oplock = 0;
575 int xid, rc; 580 int xid, rc;
576 __u16 fid; 581 __u16 fid;
582 struct cifsTconInfo *tcon;
583 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
584
585 if (IS_ERR(tlink))
586 return NULL;
577 587
588 tcon = tlink_tcon(tlink);
578 xid = GetXid(); 589 xid = GetXid();
579 590
580 rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, READ_CONTROL, 0, 591 rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL, 0,
581 &fid, &oplock, NULL, cifs_sb->local_nls, 592 &fid, &oplock, NULL, cifs_sb->local_nls,
582 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 593 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
583 if (rc) { 594 if (rc) {
@@ -585,11 +596,12 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
585 goto out; 596 goto out;
586 } 597 }
587 598
588 rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen); 599 rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
589 cFYI(1, "GetCIFSACL rc = %d ACL len %d", rc, *pacllen); 600 cFYI(1, "GetCIFSACL rc = %d ACL len %d", rc, *pacllen);
590 601
591 CIFSSMBClose(xid, cifs_sb->tcon, fid); 602 CIFSSMBClose(xid, tcon, fid);
592 out: 603 out:
604 cifs_put_tlink(tlink);
593 FreeXid(xid); 605 FreeXid(xid);
594 return pntsd; 606 return pntsd;
595} 607}
@@ -603,7 +615,7 @@ static struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
603 struct cifsFileInfo *open_file = NULL; 615 struct cifsFileInfo *open_file = NULL;
604 616
605 if (inode) 617 if (inode)
606 open_file = find_readable_file(CIFS_I(inode)); 618 open_file = find_readable_file(CIFS_I(inode), true);
607 if (!open_file) 619 if (!open_file)
608 return get_cifs_acl_by_path(cifs_sb, path, pacllen); 620 return get_cifs_acl_by_path(cifs_sb, path, pacllen);
609 621
@@ -616,10 +628,15 @@ static int set_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, __u16 fid,
616 struct cifs_ntsd *pnntsd, u32 acllen) 628 struct cifs_ntsd *pnntsd, u32 acllen)
617{ 629{
618 int xid, rc; 630 int xid, rc;
631 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
632
633 if (IS_ERR(tlink))
634 return PTR_ERR(tlink);
619 635
620 xid = GetXid(); 636 xid = GetXid();
621 rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen); 637 rc = CIFSSMBSetCIFSACL(xid, tlink_tcon(tlink), fid, pnntsd, acllen);
622 FreeXid(xid); 638 FreeXid(xid);
639 cifs_put_tlink(tlink);
623 640
624 cFYI(DBG2, "SetCIFSACL rc = %d", rc); 641 cFYI(DBG2, "SetCIFSACL rc = %d", rc);
625 return rc; 642 return rc;
@@ -631,10 +648,16 @@ static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
631 int oplock = 0; 648 int oplock = 0;
632 int xid, rc; 649 int xid, rc;
633 __u16 fid; 650 __u16 fid;
651 struct cifsTconInfo *tcon;
652 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
634 653
654 if (IS_ERR(tlink))
655 return PTR_ERR(tlink);
656
657 tcon = tlink_tcon(tlink);
635 xid = GetXid(); 658 xid = GetXid();
636 659
637 rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, WRITE_DAC, 0, 660 rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, WRITE_DAC, 0,
638 &fid, &oplock, NULL, cifs_sb->local_nls, 661 &fid, &oplock, NULL, cifs_sb->local_nls,
639 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 662 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
640 if (rc) { 663 if (rc) {
@@ -642,12 +665,13 @@ static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
642 goto out; 665 goto out;
643 } 666 }
644 667
645 rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen); 668 rc = CIFSSMBSetCIFSACL(xid, tcon, fid, pnntsd, acllen);
646 cFYI(DBG2, "SetCIFSACL rc = %d", rc); 669 cFYI(DBG2, "SetCIFSACL rc = %d", rc);
647 670
648 CIFSSMBClose(xid, cifs_sb->tcon, fid); 671 CIFSSMBClose(xid, tcon, fid);
649 out: 672out:
650 FreeXid(xid); 673 FreeXid(xid);
674 cifs_put_tlink(tlink);
651 return rc; 675 return rc;
652} 676}
653 677
@@ -661,7 +685,7 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
661 685
662 cFYI(DBG2, "set ACL for %s from mode 0x%x", path, inode->i_mode); 686 cFYI(DBG2, "set ACL for %s from mode 0x%x", path, inode->i_mode);
663 687
664 open_file = find_readable_file(CIFS_I(inode)); 688 open_file = find_readable_file(CIFS_I(inode), true);
665 if (!open_file) 689 if (!open_file)
666 return set_cifs_acl_by_path(cifs_sb, path, pnntsd, acllen); 690 return set_cifs_acl_by_path(cifs_sb, path, pnntsd, acllen);
667 691
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index 35042d8f7338..89fb94fac4b5 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -27,6 +27,7 @@
27#include "md5.h" 27#include "md5.h"
28#include "cifs_unicode.h" 28#include "cifs_unicode.h"
29#include "cifsproto.h" 29#include "cifsproto.h"
30#include "ntlmssp.h"
30#include <linux/ctype.h> 31#include <linux/ctype.h>
31#include <linux/random.h> 32#include <linux/random.h>
32 33
@@ -42,7 +43,7 @@ extern void SMBencrypt(unsigned char *passwd, const unsigned char *c8,
42 unsigned char *p24); 43 unsigned char *p24);
43 44
44static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu, 45static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu,
45 const struct mac_key *key, char *signature) 46 const struct session_key *key, char *signature)
46{ 47{
47 struct MD5Context context; 48 struct MD5Context context;
48 49
@@ -78,7 +79,7 @@ int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
78 server->sequence_number++; 79 server->sequence_number++;
79 spin_unlock(&GlobalMid_Lock); 80 spin_unlock(&GlobalMid_Lock);
80 81
81 rc = cifs_calculate_signature(cifs_pdu, &server->mac_signing_key, 82 rc = cifs_calculate_signature(cifs_pdu, &server->session_key,
82 smb_signature); 83 smb_signature);
83 if (rc) 84 if (rc)
84 memset(cifs_pdu->Signature.SecuritySignature, 0, 8); 85 memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
@@ -89,7 +90,7 @@ int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
89} 90}
90 91
91static int cifs_calc_signature2(const struct kvec *iov, int n_vec, 92static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
92 const struct mac_key *key, char *signature) 93 const struct session_key *key, char *signature)
93{ 94{
94 struct MD5Context context; 95 struct MD5Context context;
95 int i; 96 int i;
@@ -145,7 +146,7 @@ int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
145 server->sequence_number++; 146 server->sequence_number++;
146 spin_unlock(&GlobalMid_Lock); 147 spin_unlock(&GlobalMid_Lock);
147 148
148 rc = cifs_calc_signature2(iov, n_vec, &server->mac_signing_key, 149 rc = cifs_calc_signature2(iov, n_vec, &server->session_key,
149 smb_signature); 150 smb_signature);
150 if (rc) 151 if (rc)
151 memset(cifs_pdu->Signature.SecuritySignature, 0, 8); 152 memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
@@ -156,14 +157,14 @@ int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
156} 157}
157 158
158int cifs_verify_signature(struct smb_hdr *cifs_pdu, 159int cifs_verify_signature(struct smb_hdr *cifs_pdu,
159 const struct mac_key *mac_key, 160 const struct session_key *session_key,
160 __u32 expected_sequence_number) 161 __u32 expected_sequence_number)
161{ 162{
162 unsigned int rc; 163 unsigned int rc;
163 char server_response_sig[8]; 164 char server_response_sig[8];
164 char what_we_think_sig_should_be[20]; 165 char what_we_think_sig_should_be[20];
165 166
166 if ((cifs_pdu == NULL) || (mac_key == NULL)) 167 if (cifs_pdu == NULL || session_key == NULL)
167 return -EINVAL; 168 return -EINVAL;
168 169
169 if (cifs_pdu->Command == SMB_COM_NEGOTIATE) 170 if (cifs_pdu->Command == SMB_COM_NEGOTIATE)
@@ -192,7 +193,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu,
192 cpu_to_le32(expected_sequence_number); 193 cpu_to_le32(expected_sequence_number);
193 cifs_pdu->Signature.Sequence.Reserved = 0; 194 cifs_pdu->Signature.Sequence.Reserved = 0;
194 195
195 rc = cifs_calculate_signature(cifs_pdu, mac_key, 196 rc = cifs_calculate_signature(cifs_pdu, session_key,
196 what_we_think_sig_should_be); 197 what_we_think_sig_should_be);
197 198
198 if (rc) 199 if (rc)
@@ -209,7 +210,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu,
209} 210}
210 211
211/* We fill in key by putting in 40 byte array which was allocated by caller */ 212/* We fill in key by putting in 40 byte array which was allocated by caller */
212int cifs_calculate_mac_key(struct mac_key *key, const char *rn, 213int cifs_calculate_session_key(struct session_key *key, const char *rn,
213 const char *password) 214 const char *password)
214{ 215{
215 char temp_key[16]; 216 char temp_key[16];
@@ -262,6 +263,90 @@ void calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
262} 263}
263#endif /* CIFS_WEAK_PW_HASH */ 264#endif /* CIFS_WEAK_PW_HASH */
264 265
266/* This is just a filler for ntlmv2 type of security mechanisms.
267 * Older servers are not very particular about the contents of av pairs
268 * in the blob and for sec mechs like ntlmv2, there is no negotiation
269 * as in ntlmssp, so unless domain and server netbios and dns names
270 * are specified, there is no way to obtain name. In case of ntlmssp,
271 * server provides that info in type 2 challenge packet
272 */
273static int
274build_avpair_blob(struct cifsSesInfo *ses)
275{
276 struct ntlmssp2_name *attrptr;
277
278 ses->tilen = 2 * sizeof(struct ntlmssp2_name);
279 ses->tiblob = kzalloc(ses->tilen, GFP_KERNEL);
280 if (!ses->tiblob) {
281 ses->tilen = 0;
282 cERROR(1, "Challenge target info allocation failure");
283 return -ENOMEM;
284 }
285 attrptr = (struct ntlmssp2_name *) ses->tiblob;
286 attrptr->type = cpu_to_le16(NTLMSSP_DOMAIN_TYPE);
287
288 return 0;
289}
290
291/* Server has provided av pairs/target info in the type 2 challenge
292 * packet and we have plucked it and stored within smb session.
293 * We parse that blob here to find netbios domain name to be used
294 * as part of ntlmv2 authentication (in Target String), if not already
295 * specified on the command line.
296 * If this function returns without any error but without fetching
297 * domain name, authentication may fail against some server but
298 * may not fail against other (those who are not very particular
299 * about target string i.e. for some, just user name might suffice.
300 */
301static int
302find_domain_name(struct cifsSesInfo *ses)
303{
304 unsigned int attrsize;
305 unsigned int type;
306 unsigned int onesize = sizeof(struct ntlmssp2_name);
307 unsigned char *blobptr;
308 unsigned char *blobend;
309 struct ntlmssp2_name *attrptr;
310
311 if (!ses->tilen || !ses->tiblob)
312 return 0;
313
314 blobptr = ses->tiblob;
315 blobend = ses->tiblob + ses->tilen;
316
317 while (blobptr + onesize < blobend) {
318 attrptr = (struct ntlmssp2_name *) blobptr;
319 type = le16_to_cpu(attrptr->type);
320 if (type == NTLMSSP_AV_EOL)
321 break;
322 blobptr += 2; /* advance attr type */
323 attrsize = le16_to_cpu(attrptr->length);
324 blobptr += 2; /* advance attr size */
325 if (blobptr + attrsize > blobend)
326 break;
327 if (type == NTLMSSP_AV_NB_DOMAIN_NAME) {
328 if (!attrsize)
329 break;
330 if (!ses->domainName) {
331 struct nls_table *default_nls;
332 ses->domainName =
333 kmalloc(attrsize + 1, GFP_KERNEL);
334 if (!ses->domainName)
335 return -ENOMEM;
336 default_nls = load_nls_default();
337 cifs_from_ucs2(ses->domainName,
338 (__le16 *)blobptr, attrsize, attrsize,
339 default_nls, false);
340 unload_nls(default_nls);
341 break;
342 }
343 }
344 blobptr += attrsize; /* advance attr value */
345 }
346
347 return 0;
348}
349
265static int calc_ntlmv2_hash(struct cifsSesInfo *ses, 350static int calc_ntlmv2_hash(struct cifsSesInfo *ses,
266 const struct nls_table *nls_cp) 351 const struct nls_table *nls_cp)
267{ 352{
@@ -321,7 +406,8 @@ calc_exit_2:
321 return rc; 406 return rc;
322} 407}
323 408
324void setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf, 409int
410setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf,
325 const struct nls_table *nls_cp) 411 const struct nls_table *nls_cp)
326{ 412{
327 int rc; 413 int rc;
@@ -333,25 +419,48 @@ void setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf,
333 buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 419 buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
334 get_random_bytes(&buf->client_chal, sizeof(buf->client_chal)); 420 get_random_bytes(&buf->client_chal, sizeof(buf->client_chal));
335 buf->reserved2 = 0; 421 buf->reserved2 = 0;
336 buf->names[0].type = cpu_to_le16(NTLMSSP_DOMAIN_TYPE); 422
337 buf->names[0].length = 0; 423 if (ses->server->secType == RawNTLMSSP) {
338 buf->names[1].type = 0; 424 if (!ses->domainName) {
339 buf->names[1].length = 0; 425 rc = find_domain_name(ses);
426 if (rc) {
427 cERROR(1, "error %d finding domain name", rc);
428 goto setup_ntlmv2_rsp_ret;
429 }
430 }
431 } else {
432 rc = build_avpair_blob(ses);
433 if (rc) {
434 cERROR(1, "error %d building av pair blob", rc);
435 return rc;
436 }
437 }
340 438
341 /* calculate buf->ntlmv2_hash */ 439 /* calculate buf->ntlmv2_hash */
342 rc = calc_ntlmv2_hash(ses, nls_cp); 440 rc = calc_ntlmv2_hash(ses, nls_cp);
343 if (rc) 441 if (rc) {
344 cERROR(1, "could not get v2 hash rc %d", rc); 442 cERROR(1, "could not get v2 hash rc %d", rc);
443 goto setup_ntlmv2_rsp_ret;
444 }
345 CalcNTLMv2_response(ses, resp_buf); 445 CalcNTLMv2_response(ses, resp_buf);
346 446
347 /* now calculate the MAC key for NTLMv2 */ 447 /* now calculate the MAC key for NTLMv2 */
348 hmac_md5_init_limK_to_64(ses->server->ntlmv2_hash, 16, &context); 448 hmac_md5_init_limK_to_64(ses->server->ntlmv2_hash, 16, &context);
349 hmac_md5_update(resp_buf, 16, &context); 449 hmac_md5_update(resp_buf, 16, &context);
350 hmac_md5_final(ses->server->mac_signing_key.data.ntlmv2.key, &context); 450 hmac_md5_final(ses->server->session_key.data.ntlmv2.key, &context);
351 451
352 memcpy(&ses->server->mac_signing_key.data.ntlmv2.resp, resp_buf, 452 memcpy(&ses->server->session_key.data.ntlmv2.resp, resp_buf,
353 sizeof(struct ntlmv2_resp)); 453 sizeof(struct ntlmv2_resp));
354 ses->server->mac_signing_key.len = 16 + sizeof(struct ntlmv2_resp); 454 ses->server->session_key.len = 16 + sizeof(struct ntlmv2_resp);
455
456 return 0;
457
458setup_ntlmv2_rsp_ret:
459 kfree(ses->tiblob);
460 ses->tiblob = NULL;
461 ses->tilen = 0;
462
463 return rc;
355} 464}
356 465
357void CalcNTLMv2_response(const struct cifsSesInfo *ses, 466void CalcNTLMv2_response(const struct cifsSesInfo *ses,
@@ -365,6 +474,9 @@ void CalcNTLMv2_response(const struct cifsSesInfo *ses,
365 hmac_md5_update(v2_session_response+8, 474 hmac_md5_update(v2_session_response+8,
366 sizeof(struct ntlmv2_resp) - 8, &context); 475 sizeof(struct ntlmv2_resp) - 8, &context);
367 476
477 if (ses->tilen)
478 hmac_md5_update(ses->tiblob, ses->tilen, &context);
479
368 hmac_md5_final(v2_session_response, &context); 480 hmac_md5_final(v2_session_response, &context);
369/* cifs_dump_mem("v2_sess_rsp: ", v2_session_response, 32); */ 481/* cifs_dump_mem("v2_sess_rsp: ", v2_session_response, 32); */
370} 482}
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index b7431afdd76d..c96345c3314d 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -36,6 +36,7 @@
36#include <linux/kthread.h> 36#include <linux/kthread.h>
37#include <linux/freezer.h> 37#include <linux/freezer.h>
38#include <linux/smp_lock.h> 38#include <linux/smp_lock.h>
39#include <net/ipv6.h>
39#include "cifsfs.h" 40#include "cifsfs.h"
40#include "cifspdu.h" 41#include "cifspdu.h"
41#define DECLARE_GLOBALS_HERE 42#define DECLARE_GLOBALS_HERE
@@ -136,9 +137,6 @@ cifs_read_super(struct super_block *sb, void *data,
136 sb->s_magic = CIFS_MAGIC_NUMBER; 137 sb->s_magic = CIFS_MAGIC_NUMBER;
137 sb->s_op = &cifs_super_ops; 138 sb->s_op = &cifs_super_ops;
138 sb->s_bdi = &cifs_sb->bdi; 139 sb->s_bdi = &cifs_sb->bdi;
139/* if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512)
140 sb->s_blocksize =
141 cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */
142 sb->s_blocksize = CIFS_MAX_MSGSIZE; 140 sb->s_blocksize = CIFS_MAX_MSGSIZE;
143 sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */ 141 sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */
144 inode = cifs_root_iget(sb, ROOT_I); 142 inode = cifs_root_iget(sb, ROOT_I);
@@ -224,7 +222,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
224{ 222{
225 struct super_block *sb = dentry->d_sb; 223 struct super_block *sb = dentry->d_sb;
226 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 224 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
227 struct cifsTconInfo *tcon = cifs_sb->tcon; 225 struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
228 int rc = -EOPNOTSUPP; 226 int rc = -EOPNOTSUPP;
229 int xid; 227 int xid;
230 228
@@ -366,14 +364,36 @@ static int
366cifs_show_options(struct seq_file *s, struct vfsmount *m) 364cifs_show_options(struct seq_file *s, struct vfsmount *m)
367{ 365{
368 struct cifs_sb_info *cifs_sb = CIFS_SB(m->mnt_sb); 366 struct cifs_sb_info *cifs_sb = CIFS_SB(m->mnt_sb);
369 struct cifsTconInfo *tcon = cifs_sb->tcon; 367 struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
368 struct sockaddr *srcaddr;
369 srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr;
370 370
371 seq_printf(s, ",unc=%s", tcon->treeName); 371 seq_printf(s, ",unc=%s", tcon->treeName);
372 if (tcon->ses->userName) 372
373 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)
374 seq_printf(s, ",multiuser");
375 else if (tcon->ses->userName)
373 seq_printf(s, ",username=%s", tcon->ses->userName); 376 seq_printf(s, ",username=%s", tcon->ses->userName);
377
374 if (tcon->ses->domainName) 378 if (tcon->ses->domainName)
375 seq_printf(s, ",domain=%s", tcon->ses->domainName); 379 seq_printf(s, ",domain=%s", tcon->ses->domainName);
376 380
381 if (srcaddr->sa_family != AF_UNSPEC) {
382 struct sockaddr_in *saddr4;
383 struct sockaddr_in6 *saddr6;
384 saddr4 = (struct sockaddr_in *)srcaddr;
385 saddr6 = (struct sockaddr_in6 *)srcaddr;
386 if (srcaddr->sa_family == AF_INET6)
387 seq_printf(s, ",srcaddr=%pI6c",
388 &saddr6->sin6_addr);
389 else if (srcaddr->sa_family == AF_INET)
390 seq_printf(s, ",srcaddr=%pI4",
391 &saddr4->sin_addr.s_addr);
392 else
393 seq_printf(s, ",srcaddr=BAD-AF:%i",
394 (int)(srcaddr->sa_family));
395 }
396
377 seq_printf(s, ",uid=%d", cifs_sb->mnt_uid); 397 seq_printf(s, ",uid=%d", cifs_sb->mnt_uid);
378 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) 398 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
379 seq_printf(s, ",forceuid"); 399 seq_printf(s, ",forceuid");
@@ -422,6 +442,8 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
422 seq_printf(s, ",dynperm"); 442 seq_printf(s, ",dynperm");
423 if (m->mnt_sb->s_flags & MS_POSIXACL) 443 if (m->mnt_sb->s_flags & MS_POSIXACL)
424 seq_printf(s, ",acl"); 444 seq_printf(s, ",acl");
445 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
446 seq_printf(s, ",mfsymlinks");
425 447
426 seq_printf(s, ",rsize=%d", cifs_sb->rsize); 448 seq_printf(s, ",rsize=%d", cifs_sb->rsize);
427 seq_printf(s, ",wsize=%d", cifs_sb->wsize); 449 seq_printf(s, ",wsize=%d", cifs_sb->wsize);
@@ -437,9 +459,7 @@ static void cifs_umount_begin(struct super_block *sb)
437 if (cifs_sb == NULL) 459 if (cifs_sb == NULL)
438 return; 460 return;
439 461
440 tcon = cifs_sb->tcon; 462 tcon = cifs_sb_master_tcon(cifs_sb);
441 if (tcon == NULL)
442 return;
443 463
444 read_lock(&cifs_tcp_ses_lock); 464 read_lock(&cifs_tcp_ses_lock);
445 if ((tcon->tc_count > 1) || (tcon->tidStatus == CifsExiting)) { 465 if ((tcon->tc_count > 1) || (tcon->tidStatus == CifsExiting)) {
@@ -568,6 +588,7 @@ static int cifs_setlease(struct file *file, long arg, struct file_lock **lease)
568 /* note that this is called by vfs setlease with the BKL held 588 /* note that this is called by vfs setlease with the BKL held
569 although I doubt that BKL is needed here in cifs */ 589 although I doubt that BKL is needed here in cifs */
570 struct inode *inode = file->f_path.dentry->d_inode; 590 struct inode *inode = file->f_path.dentry->d_inode;
591 struct cifsFileInfo *cfile = file->private_data;
571 592
572 if (!(S_ISREG(inode->i_mode))) 593 if (!(S_ISREG(inode->i_mode)))
573 return -EINVAL; 594 return -EINVAL;
@@ -578,8 +599,8 @@ static int cifs_setlease(struct file *file, long arg, struct file_lock **lease)
578 ((arg == F_WRLCK) && 599 ((arg == F_WRLCK) &&
579 (CIFS_I(inode)->clientCanCacheAll))) 600 (CIFS_I(inode)->clientCanCacheAll)))
580 return generic_setlease(file, arg, lease); 601 return generic_setlease(file, arg, lease);
581 else if (CIFS_SB(inode->i_sb)->tcon->local_lease && 602 else if (tlink_tcon(cfile->tlink)->local_lease &&
582 !CIFS_I(inode)->clientCanCacheRead) 603 !CIFS_I(inode)->clientCanCacheRead)
583 /* If the server claims to support oplock on this 604 /* If the server claims to support oplock on this
584 file, then we still need to check oplock even 605 file, then we still need to check oplock even
585 if the local_lease mount option is set, but there 606 if the local_lease mount option is set, but there
@@ -912,11 +933,11 @@ init_cifs(void)
912 933
913 rc = cifs_fscache_register(); 934 rc = cifs_fscache_register();
914 if (rc) 935 if (rc)
915 goto out; 936 goto out_clean_proc;
916 937
917 rc = cifs_init_inodecache(); 938 rc = cifs_init_inodecache();
918 if (rc) 939 if (rc)
919 goto out_clean_proc; 940 goto out_unreg_fscache;
920 941
921 rc = cifs_init_mids(); 942 rc = cifs_init_mids();
922 if (rc) 943 if (rc)
@@ -938,19 +959,19 @@ init_cifs(void)
938 return 0; 959 return 0;
939 960
940#ifdef CONFIG_CIFS_UPCALL 961#ifdef CONFIG_CIFS_UPCALL
941 out_unregister_filesystem: 962out_unregister_filesystem:
942 unregister_filesystem(&cifs_fs_type); 963 unregister_filesystem(&cifs_fs_type);
943#endif 964#endif
944 out_destroy_request_bufs: 965out_destroy_request_bufs:
945 cifs_destroy_request_bufs(); 966 cifs_destroy_request_bufs();
946 out_destroy_mids: 967out_destroy_mids:
947 cifs_destroy_mids(); 968 cifs_destroy_mids();
948 out_destroy_inodecache: 969out_destroy_inodecache:
949 cifs_destroy_inodecache(); 970 cifs_destroy_inodecache();
950 out_clean_proc: 971out_unreg_fscache:
951 cifs_proc_clean();
952 cifs_fscache_unregister(); 972 cifs_fscache_unregister();
953 out: 973out_clean_proc:
974 cifs_proc_clean();
954 return rc; 975 return rc;
955} 976}
956 977
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index d82f5fb4761e..786bdf36aebf 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -104,7 +104,7 @@ extern int cifs_readlink(struct dentry *direntry, char __user *buffer,
104extern int cifs_symlink(struct inode *inode, struct dentry *direntry, 104extern int cifs_symlink(struct inode *inode, struct dentry *direntry,
105 const char *symname); 105 const char *symname);
106extern int cifs_removexattr(struct dentry *, const char *); 106extern int cifs_removexattr(struct dentry *, const char *);
107extern int cifs_setxattr(struct dentry *, const char *, const void *, 107extern int cifs_setxattr(struct dentry *, const char *, const void *,
108 size_t, int); 108 size_t, int);
109extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); 109extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
110extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); 110extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 0cdfb8c32ac6..4f85dfdf197d 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -97,7 +97,7 @@ enum protocolEnum {
97 /* Netbios frames protocol not supported at this time */ 97 /* Netbios frames protocol not supported at this time */
98}; 98};
99 99
100struct mac_key { 100struct session_key {
101 unsigned int len; 101 unsigned int len;
102 union { 102 union {
103 char ntlm[CIFS_SESS_KEY_SIZE + 16]; 103 char ntlm[CIFS_SESS_KEY_SIZE + 16];
@@ -139,6 +139,7 @@ struct TCP_Server_Info {
139 struct sockaddr_in sockAddr; 139 struct sockaddr_in sockAddr;
140 struct sockaddr_in6 sockAddr6; 140 struct sockaddr_in6 sockAddr6;
141 } addr; 141 } addr;
142 struct sockaddr_storage srcaddr; /* locally bind to this IP */
142 wait_queue_head_t response_q; 143 wait_queue_head_t response_q;
143 wait_queue_head_t request_q; /* if more than maxmpx to srvr must block*/ 144 wait_queue_head_t request_q; /* if more than maxmpx to srvr must block*/
144 struct list_head pending_mid_q; 145 struct list_head pending_mid_q;
@@ -182,7 +183,7 @@ struct TCP_Server_Info {
182 /* 16th byte of RFC1001 workstation name is always null */ 183 /* 16th byte of RFC1001 workstation name is always null */
183 char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL]; 184 char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL];
184 __u32 sequence_number; /* needed for CIFS PDU signature */ 185 __u32 sequence_number; /* needed for CIFS PDU signature */
185 struct mac_key mac_signing_key; 186 struct session_key session_key;
186 char ntlmv2_hash[16]; 187 char ntlmv2_hash[16];
187 unsigned long lstrp; /* when we got last response from this server */ 188 unsigned long lstrp; /* when we got last response from this server */
188 u16 dialect; /* dialect index that server chose */ 189 u16 dialect; /* dialect index that server chose */
@@ -222,6 +223,8 @@ struct cifsSesInfo {
222 char userName[MAX_USERNAME_SIZE + 1]; 223 char userName[MAX_USERNAME_SIZE + 1];
223 char *domainName; 224 char *domainName;
224 char *password; 225 char *password;
226 unsigned int tilen; /* length of the target info blob */
227 unsigned char *tiblob; /* target info blob in challenge response */
225 bool need_reconnect:1; /* connection reset, uid now invalid */ 228 bool need_reconnect:1; /* connection reset, uid now invalid */
226}; 229};
227/* no more than one of the following three session flags may be set */ 230/* no more than one of the following three session flags may be set */
@@ -308,6 +311,44 @@ struct cifsTconInfo {
308}; 311};
309 312
310/* 313/*
314 * This is a refcounted and timestamped container for a tcon pointer. The
315 * container holds a tcon reference. It is considered safe to free one of
316 * these when the tl_count goes to 0. The tl_time is the time of the last
317 * "get" on the container.
318 */
319struct tcon_link {
320 unsigned long tl_index;
321 unsigned long tl_flags;
322#define TCON_LINK_MASTER 0
323#define TCON_LINK_PENDING 1
324#define TCON_LINK_IN_TREE 2
325 unsigned long tl_time;
326 atomic_t tl_count;
327 struct cifsTconInfo *tl_tcon;
328};
329
330extern struct tcon_link *cifs_sb_tlink(struct cifs_sb_info *cifs_sb);
331
332static inline struct cifsTconInfo *
333tlink_tcon(struct tcon_link *tlink)
334{
335 return tlink->tl_tcon;
336}
337
338extern void cifs_put_tlink(struct tcon_link *tlink);
339
340static inline struct tcon_link *
341cifs_get_tlink(struct tcon_link *tlink)
342{
343 if (tlink && !IS_ERR(tlink))
344 atomic_inc(&tlink->tl_count);
345 return tlink;
346}
347
348/* This function is always expected to succeed */
349extern struct cifsTconInfo *cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb);
350
351/*
311 * This info hangs off the cifsFileInfo structure, pointed to by llist. 352 * This info hangs off the cifsFileInfo structure, pointed to by llist.
312 * This is used to track byte stream locks on the file 353 * This is used to track byte stream locks on the file
313 */ 354 */
@@ -348,6 +389,7 @@ struct cifsFileInfo {
348 struct file *pfile; /* needed for writepage */ 389 struct file *pfile; /* needed for writepage */
349 struct inode *pInode; /* needed for oplock break */ 390 struct inode *pInode; /* needed for oplock break */
350 struct vfsmount *mnt; 391 struct vfsmount *mnt;
392 struct tcon_link *tlink;
351 struct mutex lock_mutex; 393 struct mutex lock_mutex;
352 struct list_head llist; /* list of byte range locks we have. */ 394 struct list_head llist; /* list of byte range locks we have. */
353 bool closePend:1; /* file is marked to close */ 395 bool closePend:1; /* file is marked to close */
@@ -369,6 +411,7 @@ static inline void cifsFileInfo_get(struct cifsFileInfo *cifs_file)
369static inline void cifsFileInfo_put(struct cifsFileInfo *cifs_file) 411static inline void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
370{ 412{
371 if (atomic_dec_and_test(&cifs_file->count)) { 413 if (atomic_dec_and_test(&cifs_file->count)) {
414 cifs_put_tlink(cifs_file->tlink);
372 iput(cifs_file->pInode); 415 iput(cifs_file->pInode);
373 kfree(cifs_file); 416 kfree(cifs_file);
374 } 417 }
@@ -474,16 +517,16 @@ struct oplock_q_entry {
474 517
475/* for pending dnotify requests */ 518/* for pending dnotify requests */
476struct dir_notify_req { 519struct dir_notify_req {
477 struct list_head lhead; 520 struct list_head lhead;
478 __le16 Pid; 521 __le16 Pid;
479 __le16 PidHigh; 522 __le16 PidHigh;
480 __u16 Mid; 523 __u16 Mid;
481 __u16 Tid; 524 __u16 Tid;
482 __u16 Uid; 525 __u16 Uid;
483 __u16 netfid; 526 __u16 netfid;
484 __u32 filter; /* CompletionFilter (for multishot) */ 527 __u32 filter; /* CompletionFilter (for multishot) */
485 int multishot; 528 int multishot;
486 struct file *pfile; 529 struct file *pfile;
487}; 530};
488 531
489struct dfs_info3_param { 532struct dfs_info3_param {
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index 14d036d8db11..b0f4b5656d4c 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -663,7 +663,6 @@ struct ntlmv2_resp {
663 __le64 time; 663 __le64 time;
664 __u64 client_chal; /* random */ 664 __u64 client_chal; /* random */
665 __u32 reserved2; 665 __u32 reserved2;
666 struct ntlmssp2_name names[2];
667 /* array of name entries could follow ending in minimum 4 byte struct */ 666 /* array of name entries could follow ending in minimum 4 byte struct */
668} __attribute__((packed)); 667} __attribute__((packed));
669 668
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 1d60c655e3e0..29a2ee8ae51f 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -78,9 +78,9 @@ extern int checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length);
78extern bool is_valid_oplock_break(struct smb_hdr *smb, 78extern bool is_valid_oplock_break(struct smb_hdr *smb,
79 struct TCP_Server_Info *); 79 struct TCP_Server_Info *);
80extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof); 80extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof);
81extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *); 81extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool);
82#ifdef CONFIG_CIFS_EXPERIMENTAL 82#ifdef CONFIG_CIFS_EXPERIMENTAL
83extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *); 83extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool);
84#endif 84#endif
85extern unsigned int smbCalcSize(struct smb_hdr *ptr); 85extern unsigned int smbCalcSize(struct smb_hdr *ptr);
86extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr); 86extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr);
@@ -107,7 +107,8 @@ extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time,
107 107
108extern struct cifsFileInfo *cifs_new_fileinfo(struct inode *newinode, 108extern struct cifsFileInfo *cifs_new_fileinfo(struct inode *newinode,
109 __u16 fileHandle, struct file *file, 109 __u16 fileHandle, struct file *file,
110 struct vfsmount *mnt, unsigned int oflags); 110 struct vfsmount *mnt, struct tcon_link *tlink,
111 unsigned int oflags, __u32 oplock);
111extern int cifs_posix_open(char *full_path, struct inode **pinode, 112extern int cifs_posix_open(char *full_path, struct inode **pinode,
112 struct super_block *sb, 113 struct super_block *sb,
113 int mode, int oflags, 114 int mode, int oflags,
@@ -362,12 +363,12 @@ extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *);
362extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, 363extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
363 __u32 *); 364 __u32 *);
364extern int cifs_verify_signature(struct smb_hdr *, 365extern int cifs_verify_signature(struct smb_hdr *,
365 const struct mac_key *mac_key, 366 const struct session_key *session_key,
366 __u32 expected_sequence_number); 367 __u32 expected_sequence_number);
367extern int cifs_calculate_mac_key(struct mac_key *key, const char *rn, 368extern int cifs_calculate_session_key(struct session_key *key, const char *rn,
368 const char *pass); 369 const char *pass);
369extern void CalcNTLMv2_response(const struct cifsSesInfo *, char *); 370extern void CalcNTLMv2_response(const struct cifsSesInfo *, char *);
370extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *, 371extern int setup_ntlmv2_rsp(struct cifsSesInfo *, char *,
371 const struct nls_table *); 372 const struct nls_table *);
372#ifdef CONFIG_CIFS_WEAK_PW_HASH 373#ifdef CONFIG_CIFS_WEAK_PW_HASH
373extern void calc_lanman_hash(const char *password, const char *cryptkey, 374extern void calc_lanman_hash(const char *password, const char *cryptkey,
@@ -408,4 +409,8 @@ extern int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
408extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon, 409extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
409 const int netfid, __u64 *pExtAttrBits, __u64 *pMask); 410 const int netfid, __u64 *pExtAttrBits, __u64 *pMask);
410extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb); 411extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb);
412extern bool CIFSCouldBeMFSymlink(const struct cifs_fattr *fattr);
413extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr,
414 const unsigned char *path,
415 struct cifs_sb_info *cifs_sb, int xid);
411#endif /* _CIFSPROTO_H */ 416#endif /* _CIFSPROTO_H */
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 7e83b356cc9e..54bd83af772c 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -620,13 +620,15 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
620 rc = 0; 620 rc = 0;
621 else 621 else
622 rc = -EINVAL; 622 rc = -EINVAL;
623 623 if (server->secType == Kerberos) {
624 if (server->sec_kerberos || server->sec_mskerberos) 624 if (!server->sec_kerberos &&
625 server->secType = Kerberos; 625 !server->sec_mskerberos)
626 else if (server->sec_ntlmssp) 626 rc = -EOPNOTSUPP;
627 server->secType = RawNTLMSSP; 627 } else if (server->secType == RawNTLMSSP) {
628 else 628 if (!server->sec_ntlmssp)
629 rc = -EOPNOTSUPP; 629 rc = -EOPNOTSUPP;
630 } else
631 rc = -EOPNOTSUPP;
630 } 632 }
631 } else 633 } else
632 server->capabilities &= ~CAP_EXTENDED_SECURITY; 634 server->capabilities &= ~CAP_EXTENDED_SECURITY;
diff --git a/fs/cifs/cn_cifs.h b/fs/cifs/cn_cifs.h
deleted file mode 100644
index ea59ccac2eb1..000000000000
--- a/fs/cifs/cn_cifs.h
+++ /dev/null
@@ -1,37 +0,0 @@
1/*
2 * fs/cifs/cn_cifs.h
3 *
4 * Copyright (c) International Business Machines Corp., 2002
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 _CN_CIFS_H
23#define _CN_CIFS_H
24#ifdef CONFIG_CIFS_UPCALL
25#include <linux/types.h>
26#include <linux/connector.h>
27
28struct cifs_upcall {
29 char signature[4]; /* CIFS */
30 enum command {
31 CIFS_GET_IP = 0x00000001, /* get ip address for hostname */
32 CIFS_GET_SECBLOB = 0x00000002, /* get SPNEGO wrapped blob */
33 } command;
34 /* union cifs upcall data follows */
35};
36#endif /* CIFS_UPCALL */
37#endif /* _CN_CIFS_H */
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 88c84a38bccb..4944fc84d5ef 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -47,7 +47,6 @@
47#include "ntlmssp.h" 47#include "ntlmssp.h"
48#include "nterr.h" 48#include "nterr.h"
49#include "rfc1002pdu.h" 49#include "rfc1002pdu.h"
50#include "cn_cifs.h"
51#include "fscache.h" 50#include "fscache.h"
52 51
53#define CIFS_PORT 445 52#define CIFS_PORT 445
@@ -100,16 +99,24 @@ struct smb_vol {
100 bool noautotune:1; 99 bool noautotune:1;
101 bool nostrictsync:1; /* do not force expensive SMBflush on every sync */ 100 bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
102 bool fsc:1; /* enable fscache */ 101 bool fsc:1; /* enable fscache */
102 bool mfsymlinks:1; /* use Minshall+French Symlinks */
103 bool multiuser:1;
103 unsigned int rsize; 104 unsigned int rsize;
104 unsigned int wsize; 105 unsigned int wsize;
105 bool sockopt_tcp_nodelay:1; 106 bool sockopt_tcp_nodelay:1;
106 unsigned short int port; 107 unsigned short int port;
107 char *prepath; 108 char *prepath;
109 struct sockaddr_storage srcaddr; /* allow binding to a local IP */
108 struct nls_table *local_nls; 110 struct nls_table *local_nls;
109}; 111};
110 112
113/* FIXME: should these be tunable? */
114#define TLINK_ERROR_EXPIRE (1 * HZ)
115#define TLINK_IDLE_EXPIRE (600 * HZ)
116
111static int ipv4_connect(struct TCP_Server_Info *server); 117static int ipv4_connect(struct TCP_Server_Info *server);
112static int ipv6_connect(struct TCP_Server_Info *server); 118static int ipv6_connect(struct TCP_Server_Info *server);
119static void cifs_prune_tlinks(struct work_struct *work);
113 120
114/* 121/*
115 * cifs tcp session reconnection 122 * cifs tcp session reconnection
@@ -1046,6 +1053,22 @@ cifs_parse_mount_options(char *options, const char *devname,
1046 "long\n"); 1053 "long\n");
1047 return 1; 1054 return 1;
1048 } 1055 }
1056 } else if (strnicmp(data, "srcaddr", 7) == 0) {
1057 vol->srcaddr.ss_family = AF_UNSPEC;
1058
1059 if (!value || !*value) {
1060 printk(KERN_WARNING "CIFS: srcaddr value"
1061 " not specified.\n");
1062 return 1; /* needs_arg; */
1063 }
1064 i = cifs_convert_address((struct sockaddr *)&vol->srcaddr,
1065 value, strlen(value));
1066 if (i < 0) {
1067 printk(KERN_WARNING "CIFS: Could not parse"
1068 " srcaddr: %s\n",
1069 value);
1070 return 1;
1071 }
1049 } else if (strnicmp(data, "prefixpath", 10) == 0) { 1072 } else if (strnicmp(data, "prefixpath", 10) == 0) {
1050 if (!value || !*value) { 1073 if (!value || !*value) {
1051 printk(KERN_WARNING 1074 printk(KERN_WARNING
@@ -1325,6 +1348,10 @@ cifs_parse_mount_options(char *options, const char *devname,
1325 "/proc/fs/cifs/LookupCacheEnabled to 0\n"); 1348 "/proc/fs/cifs/LookupCacheEnabled to 0\n");
1326 } else if (strnicmp(data, "fsc", 3) == 0) { 1349 } else if (strnicmp(data, "fsc", 3) == 0) {
1327 vol->fsc = true; 1350 vol->fsc = true;
1351 } else if (strnicmp(data, "mfsymlinks", 10) == 0) {
1352 vol->mfsymlinks = true;
1353 } else if (strnicmp(data, "multiuser", 8) == 0) {
1354 vol->multiuser = true;
1328 } else 1355 } else
1329 printk(KERN_WARNING "CIFS: Unknown mount option %s\n", 1356 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
1330 data); 1357 data);
@@ -1356,6 +1383,13 @@ cifs_parse_mount_options(char *options, const char *devname,
1356 return 1; 1383 return 1;
1357 } 1384 }
1358 } 1385 }
1386
1387 if (vol->multiuser && !(vol->secFlg & CIFSSEC_MAY_KRB5)) {
1388 cERROR(1, "Multiuser mounts currently require krb5 "
1389 "authentication!");
1390 return 1;
1391 }
1392
1359 if (vol->UNCip == NULL) 1393 if (vol->UNCip == NULL)
1360 vol->UNCip = &vol->UNC[2]; 1394 vol->UNCip = &vol->UNC[2];
1361 1395
@@ -1374,8 +1408,36 @@ cifs_parse_mount_options(char *options, const char *devname,
1374 return 0; 1408 return 0;
1375} 1409}
1376 1410
1411/** Returns true if srcaddr isn't specified and rhs isn't
1412 * specified, or if srcaddr is specified and
1413 * matches the IP address of the rhs argument.
1414 */
1377static bool 1415static bool
1378match_address(struct TCP_Server_Info *server, struct sockaddr *addr) 1416srcip_matches(struct sockaddr *srcaddr, struct sockaddr *rhs)
1417{
1418 switch (srcaddr->sa_family) {
1419 case AF_UNSPEC:
1420 return (rhs->sa_family == AF_UNSPEC);
1421 case AF_INET: {
1422 struct sockaddr_in *saddr4 = (struct sockaddr_in *)srcaddr;
1423 struct sockaddr_in *vaddr4 = (struct sockaddr_in *)rhs;
1424 return (saddr4->sin_addr.s_addr == vaddr4->sin_addr.s_addr);
1425 }
1426 case AF_INET6: {
1427 struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)srcaddr;
1428 struct sockaddr_in6 *vaddr6 = (struct sockaddr_in6 *)&rhs;
1429 return ipv6_addr_equal(&saddr6->sin6_addr, &vaddr6->sin6_addr);
1430 }
1431 default:
1432 WARN_ON(1);
1433 return false; /* don't expect to be here */
1434 }
1435}
1436
1437
1438static bool
1439match_address(struct TCP_Server_Info *server, struct sockaddr *addr,
1440 struct sockaddr *srcaddr)
1379{ 1441{
1380 struct sockaddr_in *addr4 = (struct sockaddr_in *)addr; 1442 struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
1381 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr; 1443 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
@@ -1402,6 +1464,9 @@ match_address(struct TCP_Server_Info *server, struct sockaddr *addr)
1402 break; 1464 break;
1403 } 1465 }
1404 1466
1467 if (!srcip_matches(srcaddr, (struct sockaddr *)&server->srcaddr))
1468 return false;
1469
1405 return true; 1470 return true;
1406} 1471}
1407 1472
@@ -1460,16 +1525,8 @@ cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol)
1460 1525
1461 write_lock(&cifs_tcp_ses_lock); 1526 write_lock(&cifs_tcp_ses_lock);
1462 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) { 1527 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
1463 /* 1528 if (!match_address(server, addr,
1464 * the demux thread can exit on its own while still in CifsNew 1529 (struct sockaddr *)&vol->srcaddr))
1465 * so don't accept any sockets in that state. Since the
1466 * tcpStatus never changes back to CifsNew it's safe to check
1467 * for this without a lock.
1468 */
1469 if (server->tcpStatus == CifsNew)
1470 continue;
1471
1472 if (!match_address(server, addr))
1473 continue; 1530 continue;
1474 1531
1475 if (!match_security(server, vol)) 1532 if (!match_security(server, vol))
@@ -1584,6 +1641,8 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1584 * no need to spinlock this init of tcpStatus or srv_count 1641 * no need to spinlock this init of tcpStatus or srv_count
1585 */ 1642 */
1586 tcp_ses->tcpStatus = CifsNew; 1643 tcp_ses->tcpStatus = CifsNew;
1644 memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr,
1645 sizeof(tcp_ses->srcaddr));
1587 ++tcp_ses->srv_count; 1646 ++tcp_ses->srv_count;
1588 1647
1589 if (addr.ss_family == AF_INET6) { 1648 if (addr.ss_family == AF_INET6) {
@@ -1740,6 +1799,8 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
1740 if (ses == NULL) 1799 if (ses == NULL)
1741 goto get_ses_fail; 1800 goto get_ses_fail;
1742 1801
1802 ses->tilen = 0;
1803 ses->tiblob = NULL;
1743 /* new SMB session uses our server ref */ 1804 /* new SMB session uses our server ref */
1744 ses->server = server; 1805 ses->server = server;
1745 if (server->addr.sockAddr6.sin6_family == AF_INET6) 1806 if (server->addr.sockAddr6.sin6_family == AF_INET6)
@@ -1913,6 +1974,23 @@ out_fail:
1913 return ERR_PTR(rc); 1974 return ERR_PTR(rc);
1914} 1975}
1915 1976
1977void
1978cifs_put_tlink(struct tcon_link *tlink)
1979{
1980 if (!tlink || IS_ERR(tlink))
1981 return;
1982
1983 if (!atomic_dec_and_test(&tlink->tl_count) ||
1984 test_bit(TCON_LINK_IN_TREE, &tlink->tl_flags)) {
1985 tlink->tl_time = jiffies;
1986 return;
1987 }
1988
1989 if (!IS_ERR(tlink_tcon(tlink)))
1990 cifs_put_tcon(tlink_tcon(tlink));
1991 kfree(tlink);
1992 return;
1993}
1916 1994
1917int 1995int
1918get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path, 1996get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
@@ -1997,6 +2075,33 @@ static void rfc1002mangle(char *target, char *source, unsigned int length)
1997 2075
1998} 2076}
1999 2077
2078static int
2079bind_socket(struct TCP_Server_Info *server)
2080{
2081 int rc = 0;
2082 if (server->srcaddr.ss_family != AF_UNSPEC) {
2083 /* Bind to the specified local IP address */
2084 struct socket *socket = server->ssocket;
2085 rc = socket->ops->bind(socket,
2086 (struct sockaddr *) &server->srcaddr,
2087 sizeof(server->srcaddr));
2088 if (rc < 0) {
2089 struct sockaddr_in *saddr4;
2090 struct sockaddr_in6 *saddr6;
2091 saddr4 = (struct sockaddr_in *)&server->srcaddr;
2092 saddr6 = (struct sockaddr_in6 *)&server->srcaddr;
2093 if (saddr6->sin6_family == AF_INET6)
2094 cERROR(1, "cifs: "
2095 "Failed to bind to: %pI6c, error: %d\n",
2096 &saddr6->sin6_addr, rc);
2097 else
2098 cERROR(1, "cifs: "
2099 "Failed to bind to: %pI4, error: %d\n",
2100 &saddr4->sin_addr.s_addr, rc);
2101 }
2102 }
2103 return rc;
2104}
2000 2105
2001static int 2106static int
2002ipv4_connect(struct TCP_Server_Info *server) 2107ipv4_connect(struct TCP_Server_Info *server)
@@ -2022,6 +2127,10 @@ ipv4_connect(struct TCP_Server_Info *server)
2022 cifs_reclassify_socket4(socket); 2127 cifs_reclassify_socket4(socket);
2023 } 2128 }
2024 2129
2130 rc = bind_socket(server);
2131 if (rc < 0)
2132 return rc;
2133
2025 /* user overrode default port */ 2134 /* user overrode default port */
2026 if (server->addr.sockAddr.sin_port) { 2135 if (server->addr.sockAddr.sin_port) {
2027 rc = socket->ops->connect(socket, (struct sockaddr *) 2136 rc = socket->ops->connect(socket, (struct sockaddr *)
@@ -2184,6 +2293,10 @@ ipv6_connect(struct TCP_Server_Info *server)
2184 cifs_reclassify_socket6(socket); 2293 cifs_reclassify_socket6(socket);
2185 } 2294 }
2186 2295
2296 rc = bind_socket(server);
2297 if (rc < 0)
2298 return rc;
2299
2187 /* user overrode default port */ 2300 /* user overrode default port */
2188 if (server->addr.sockAddr6.sin6_port) { 2301 if (server->addr.sockAddr6.sin6_port) {
2189 rc = socket->ops->connect(socket, 2302 rc = socket->ops->connect(socket,
@@ -2383,6 +2496,8 @@ convert_delimiter(char *path, char delim)
2383static void setup_cifs_sb(struct smb_vol *pvolume_info, 2496static void setup_cifs_sb(struct smb_vol *pvolume_info,
2384 struct cifs_sb_info *cifs_sb) 2497 struct cifs_sb_info *cifs_sb)
2385{ 2498{
2499 INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks);
2500
2386 if (pvolume_info->rsize > CIFSMaxBufSize) { 2501 if (pvolume_info->rsize > CIFSMaxBufSize) {
2387 cERROR(1, "rsize %d too large, using MaxBufSize", 2502 cERROR(1, "rsize %d too large, using MaxBufSize",
2388 pvolume_info->rsize); 2503 pvolume_info->rsize);
@@ -2462,10 +2577,21 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
2462 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM; 2577 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
2463 if (pvolume_info->fsc) 2578 if (pvolume_info->fsc)
2464 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE; 2579 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE;
2580 if (pvolume_info->multiuser)
2581 cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_MULTIUSER |
2582 CIFS_MOUNT_NO_PERM);
2465 if (pvolume_info->direct_io) { 2583 if (pvolume_info->direct_io) {
2466 cFYI(1, "mounting share using direct i/o"); 2584 cFYI(1, "mounting share using direct i/o");
2467 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; 2585 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
2468 } 2586 }
2587 if (pvolume_info->mfsymlinks) {
2588 if (pvolume_info->sfu_emul) {
2589 cERROR(1, "mount option mfsymlinks ignored if sfu "
2590 "mount option is used");
2591 } else {
2592 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MF_SYMLINKS;
2593 }
2594 }
2469 2595
2470 if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm)) 2596 if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm))
2471 cERROR(1, "mount option dynperm ignored if cifsacl " 2597 cERROR(1, "mount option dynperm ignored if cifsacl "
@@ -2552,6 +2678,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2552 struct TCP_Server_Info *srvTcp; 2678 struct TCP_Server_Info *srvTcp;
2553 char *full_path; 2679 char *full_path;
2554 char *mount_data = mount_data_global; 2680 char *mount_data = mount_data_global;
2681 struct tcon_link *tlink;
2555#ifdef CONFIG_CIFS_DFS_UPCALL 2682#ifdef CONFIG_CIFS_DFS_UPCALL
2556 struct dfs_info3_param *referrals = NULL; 2683 struct dfs_info3_param *referrals = NULL;
2557 unsigned int num_referrals = 0; 2684 unsigned int num_referrals = 0;
@@ -2563,6 +2690,7 @@ try_mount_again:
2563 pSesInfo = NULL; 2690 pSesInfo = NULL;
2564 srvTcp = NULL; 2691 srvTcp = NULL;
2565 full_path = NULL; 2692 full_path = NULL;
2693 tlink = NULL;
2566 2694
2567 xid = GetXid(); 2695 xid = GetXid();
2568 2696
@@ -2638,8 +2766,6 @@ try_mount_again:
2638 goto remote_path_check; 2766 goto remote_path_check;
2639 } 2767 }
2640 2768
2641 cifs_sb->tcon = tcon;
2642
2643 /* do not care if following two calls succeed - informational */ 2769 /* do not care if following two calls succeed - informational */
2644 if (!tcon->ipc) { 2770 if (!tcon->ipc) {
2645 CIFSSMBQFSDeviceInfo(xid, tcon); 2771 CIFSSMBQFSDeviceInfo(xid, tcon);
@@ -2748,6 +2874,38 @@ remote_path_check:
2748#endif 2874#endif
2749 } 2875 }
2750 2876
2877 if (rc)
2878 goto mount_fail_check;
2879
2880 /* now, hang the tcon off of the superblock */
2881 tlink = kzalloc(sizeof *tlink, GFP_KERNEL);
2882 if (tlink == NULL) {
2883 rc = -ENOMEM;
2884 goto mount_fail_check;
2885 }
2886
2887 tlink->tl_index = pSesInfo->linux_uid;
2888 tlink->tl_tcon = tcon;
2889 tlink->tl_time = jiffies;
2890 set_bit(TCON_LINK_MASTER, &tlink->tl_flags);
2891 set_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
2892
2893 rc = radix_tree_preload(GFP_KERNEL);
2894 if (rc == -ENOMEM) {
2895 kfree(tlink);
2896 goto mount_fail_check;
2897 }
2898
2899 spin_lock(&cifs_sb->tlink_tree_lock);
2900 radix_tree_insert(&cifs_sb->tlink_tree, pSesInfo->linux_uid, tlink);
2901 radix_tree_tag_set(&cifs_sb->tlink_tree, pSesInfo->linux_uid,
2902 CIFS_TLINK_MASTER_TAG);
2903 spin_unlock(&cifs_sb->tlink_tree_lock);
2904 radix_tree_preload_end();
2905
2906 queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks,
2907 TLINK_IDLE_EXPIRE);
2908
2751mount_fail_check: 2909mount_fail_check:
2752 /* on error free sesinfo and tcon struct if needed */ 2910 /* on error free sesinfo and tcon struct if needed */
2753 if (rc) { 2911 if (rc) {
@@ -2934,19 +3092,39 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
2934int 3092int
2935cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) 3093cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
2936{ 3094{
2937 int rc = 0; 3095 int i, ret;
2938 char *tmp; 3096 char *tmp;
3097 struct tcon_link *tlink[8];
3098 unsigned long index = 0;
3099
3100 cancel_delayed_work_sync(&cifs_sb->prune_tlinks);
3101
3102 do {
3103 spin_lock(&cifs_sb->tlink_tree_lock);
3104 ret = radix_tree_gang_lookup(&cifs_sb->tlink_tree,
3105 (void **)tlink, index,
3106 ARRAY_SIZE(tlink));
3107 /* increment index for next pass */
3108 if (ret > 0)
3109 index = tlink[ret - 1]->tl_index + 1;
3110 for (i = 0; i < ret; i++) {
3111 cifs_get_tlink(tlink[i]);
3112 clear_bit(TCON_LINK_IN_TREE, &tlink[i]->tl_flags);
3113 radix_tree_delete(&cifs_sb->tlink_tree,
3114 tlink[i]->tl_index);
3115 }
3116 spin_unlock(&cifs_sb->tlink_tree_lock);
2939 3117
2940 if (cifs_sb->tcon) 3118 for (i = 0; i < ret; i++)
2941 cifs_put_tcon(cifs_sb->tcon); 3119 cifs_put_tlink(tlink[i]);
3120 } while (ret != 0);
2942 3121
2943 cifs_sb->tcon = NULL;
2944 tmp = cifs_sb->prepath; 3122 tmp = cifs_sb->prepath;
2945 cifs_sb->prepathlen = 0; 3123 cifs_sb->prepathlen = 0;
2946 cifs_sb->prepath = NULL; 3124 cifs_sb->prepath = NULL;
2947 kfree(tmp); 3125 kfree(tmp);
2948 3126
2949 return rc; 3127 return 0;
2950} 3128}
2951 3129
2952int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses) 3130int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses)
@@ -3007,3 +3185,237 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
3007 return rc; 3185 return rc;
3008} 3186}
3009 3187
3188static struct cifsTconInfo *
3189cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid)
3190{
3191 struct cifsTconInfo *master_tcon = cifs_sb_master_tcon(cifs_sb);
3192 struct cifsSesInfo *ses;
3193 struct cifsTconInfo *tcon = NULL;
3194 struct smb_vol *vol_info;
3195 char username[MAX_USERNAME_SIZE + 1];
3196
3197 vol_info = kzalloc(sizeof(*vol_info), GFP_KERNEL);
3198 if (vol_info == NULL) {
3199 tcon = ERR_PTR(-ENOMEM);
3200 goto out;
3201 }
3202
3203 snprintf(username, MAX_USERNAME_SIZE, "krb50x%x", fsuid);
3204 vol_info->username = username;
3205 vol_info->local_nls = cifs_sb->local_nls;
3206 vol_info->linux_uid = fsuid;
3207 vol_info->cred_uid = fsuid;
3208 vol_info->UNC = master_tcon->treeName;
3209 vol_info->retry = master_tcon->retry;
3210 vol_info->nocase = master_tcon->nocase;
3211 vol_info->local_lease = master_tcon->local_lease;
3212 vol_info->no_linux_ext = !master_tcon->unix_ext;
3213
3214 /* FIXME: allow for other secFlg settings */
3215 vol_info->secFlg = CIFSSEC_MUST_KRB5;
3216
3217 /* get a reference for the same TCP session */
3218 write_lock(&cifs_tcp_ses_lock);
3219 ++master_tcon->ses->server->srv_count;
3220 write_unlock(&cifs_tcp_ses_lock);
3221
3222 ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info);
3223 if (IS_ERR(ses)) {
3224 tcon = (struct cifsTconInfo *)ses;
3225 cifs_put_tcp_session(master_tcon->ses->server);
3226 goto out;
3227 }
3228
3229 tcon = cifs_get_tcon(ses, vol_info);
3230 if (IS_ERR(tcon)) {
3231 cifs_put_smb_ses(ses);
3232 goto out;
3233 }
3234
3235 if (ses->capabilities & CAP_UNIX)
3236 reset_cifs_unix_caps(0, tcon, NULL, vol_info);
3237out:
3238 kfree(vol_info);
3239
3240 return tcon;
3241}
3242
3243static struct tcon_link *
3244cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb)
3245{
3246 struct tcon_link *tlink;
3247 unsigned int ret;
3248
3249 spin_lock(&cifs_sb->tlink_tree_lock);
3250 ret = radix_tree_gang_lookup_tag(&cifs_sb->tlink_tree, (void **)&tlink,
3251 0, 1, CIFS_TLINK_MASTER_TAG);
3252 spin_unlock(&cifs_sb->tlink_tree_lock);
3253
3254 /* the master tcon should always be present */
3255 if (ret == 0)
3256 BUG();
3257
3258 return tlink;
3259}
3260
3261struct cifsTconInfo *
3262cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb)
3263{
3264 return tlink_tcon(cifs_sb_master_tlink(cifs_sb));
3265}
3266
3267static int
3268cifs_sb_tcon_pending_wait(void *unused)
3269{
3270 schedule();
3271 return signal_pending(current) ? -ERESTARTSYS : 0;
3272}
3273
3274/*
3275 * Find or construct an appropriate tcon given a cifs_sb and the fsuid of the
3276 * current task.
3277 *
3278 * If the superblock doesn't refer to a multiuser mount, then just return
3279 * the master tcon for the mount.
3280 *
3281 * First, search the radix tree for an existing tcon for this fsuid. If one
3282 * exists, then check to see if it's pending construction. If it is then wait
3283 * for construction to complete. Once it's no longer pending, check to see if
3284 * it failed and either return an error or retry construction, depending on
3285 * the timeout.
3286 *
3287 * If one doesn't exist then insert a new tcon_link struct into the tree and
3288 * try to construct a new one.
3289 */
3290struct tcon_link *
3291cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
3292{
3293 int ret;
3294 unsigned long fsuid = (unsigned long) current_fsuid();
3295 struct tcon_link *tlink, *newtlink;
3296
3297 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
3298 return cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
3299
3300 spin_lock(&cifs_sb->tlink_tree_lock);
3301 tlink = radix_tree_lookup(&cifs_sb->tlink_tree, fsuid);
3302 if (tlink)
3303 cifs_get_tlink(tlink);
3304 spin_unlock(&cifs_sb->tlink_tree_lock);
3305
3306 if (tlink == NULL) {
3307 newtlink = kzalloc(sizeof(*tlink), GFP_KERNEL);
3308 if (newtlink == NULL)
3309 return ERR_PTR(-ENOMEM);
3310 newtlink->tl_index = fsuid;
3311 newtlink->tl_tcon = ERR_PTR(-EACCES);
3312 set_bit(TCON_LINK_PENDING, &newtlink->tl_flags);
3313 set_bit(TCON_LINK_IN_TREE, &newtlink->tl_flags);
3314 cifs_get_tlink(newtlink);
3315
3316 ret = radix_tree_preload(GFP_KERNEL);
3317 if (ret != 0) {
3318 kfree(newtlink);
3319 return ERR_PTR(ret);
3320 }
3321
3322 spin_lock(&cifs_sb->tlink_tree_lock);
3323 /* was one inserted after previous search? */
3324 tlink = radix_tree_lookup(&cifs_sb->tlink_tree, fsuid);
3325 if (tlink) {
3326 cifs_get_tlink(tlink);
3327 spin_unlock(&cifs_sb->tlink_tree_lock);
3328 radix_tree_preload_end();
3329 kfree(newtlink);
3330 goto wait_for_construction;
3331 }
3332 ret = radix_tree_insert(&cifs_sb->tlink_tree, fsuid, newtlink);
3333 spin_unlock(&cifs_sb->tlink_tree_lock);
3334 radix_tree_preload_end();
3335 if (ret) {
3336 kfree(newtlink);
3337 return ERR_PTR(ret);
3338 }
3339 tlink = newtlink;
3340 } else {
3341wait_for_construction:
3342 ret = wait_on_bit(&tlink->tl_flags, TCON_LINK_PENDING,
3343 cifs_sb_tcon_pending_wait,
3344 TASK_INTERRUPTIBLE);
3345 if (ret) {
3346 cifs_put_tlink(tlink);
3347 return ERR_PTR(ret);
3348 }
3349
3350 /* if it's good, return it */
3351 if (!IS_ERR(tlink->tl_tcon))
3352 return tlink;
3353
3354 /* return error if we tried this already recently */
3355 if (time_before(jiffies, tlink->tl_time + TLINK_ERROR_EXPIRE)) {
3356 cifs_put_tlink(tlink);
3357 return ERR_PTR(-EACCES);
3358 }
3359
3360 if (test_and_set_bit(TCON_LINK_PENDING, &tlink->tl_flags))
3361 goto wait_for_construction;
3362 }
3363
3364 tlink->tl_tcon = cifs_construct_tcon(cifs_sb, fsuid);
3365 clear_bit(TCON_LINK_PENDING, &tlink->tl_flags);
3366 wake_up_bit(&tlink->tl_flags, TCON_LINK_PENDING);
3367
3368 if (IS_ERR(tlink->tl_tcon)) {
3369 cifs_put_tlink(tlink);
3370 return ERR_PTR(-EACCES);
3371 }
3372
3373 return tlink;
3374}
3375
3376/*
3377 * periodic workqueue job that scans tcon_tree for a superblock and closes
3378 * out tcons.
3379 */
3380static void
3381cifs_prune_tlinks(struct work_struct *work)
3382{
3383 struct cifs_sb_info *cifs_sb = container_of(work, struct cifs_sb_info,
3384 prune_tlinks.work);
3385 struct tcon_link *tlink[8];
3386 unsigned long now = jiffies;
3387 unsigned long index = 0;
3388 int i, ret;
3389
3390 do {
3391 spin_lock(&cifs_sb->tlink_tree_lock);
3392 ret = radix_tree_gang_lookup(&cifs_sb->tlink_tree,
3393 (void **)tlink, index,
3394 ARRAY_SIZE(tlink));
3395 /* increment index for next pass */
3396 if (ret > 0)
3397 index = tlink[ret - 1]->tl_index + 1;
3398 for (i = 0; i < ret; i++) {
3399 if (test_bit(TCON_LINK_MASTER, &tlink[i]->tl_flags) ||
3400 atomic_read(&tlink[i]->tl_count) != 0 ||
3401 time_after(tlink[i]->tl_time + TLINK_IDLE_EXPIRE,
3402 now)) {
3403 tlink[i] = NULL;
3404 continue;
3405 }
3406 cifs_get_tlink(tlink[i]);
3407 clear_bit(TCON_LINK_IN_TREE, &tlink[i]->tl_flags);
3408 radix_tree_delete(&cifs_sb->tlink_tree,
3409 tlink[i]->tl_index);
3410 }
3411 spin_unlock(&cifs_sb->tlink_tree_lock);
3412
3413 for (i = 0; i < ret; i++) {
3414 if (tlink[i] != NULL)
3415 cifs_put_tlink(tlink[i]);
3416 }
3417 } while (ret != 0);
3418
3419 queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks,
3420 TLINK_IDLE_EXPIRE);
3421}
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index f9ed0751cc12..e249b561ce8f 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -54,18 +54,18 @@ build_path_from_dentry(struct dentry *direntry)
54 int dfsplen; 54 int dfsplen;
55 char *full_path; 55 char *full_path;
56 char dirsep; 56 char dirsep;
57 struct cifs_sb_info *cifs_sb; 57 struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
58 struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
58 59
59 if (direntry == NULL) 60 if (direntry == NULL)
60 return NULL; /* not much we can do if dentry is freed and 61 return NULL; /* not much we can do if dentry is freed and
61 we need to reopen the file after it was closed implicitly 62 we need to reopen the file after it was closed implicitly
62 when the server crashed */ 63 when the server crashed */
63 64
64 cifs_sb = CIFS_SB(direntry->d_sb);
65 dirsep = CIFS_DIR_SEP(cifs_sb); 65 dirsep = CIFS_DIR_SEP(cifs_sb);
66 pplen = cifs_sb->prepathlen; 66 pplen = cifs_sb->prepathlen;
67 if (cifs_sb->tcon && (cifs_sb->tcon->Flags & SMB_SHARE_IS_IN_DFS)) 67 if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
68 dfsplen = strnlen(cifs_sb->tcon->treeName, MAX_TREE_SIZE + 1); 68 dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
69 else 69 else
70 dfsplen = 0; 70 dfsplen = 0;
71cifs_bp_rename_retry: 71cifs_bp_rename_retry:
@@ -117,7 +117,7 @@ cifs_bp_rename_retry:
117 /* BB test paths to Windows with '/' in the midst of prepath */ 117 /* BB test paths to Windows with '/' in the midst of prepath */
118 118
119 if (dfsplen) { 119 if (dfsplen) {
120 strncpy(full_path, cifs_sb->tcon->treeName, dfsplen); 120 strncpy(full_path, tcon->treeName, dfsplen);
121 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) { 121 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
122 int i; 122 int i;
123 for (i = 0; i < dfsplen; i++) { 123 for (i = 0; i < dfsplen; i++) {
@@ -131,28 +131,26 @@ cifs_bp_rename_retry:
131} 131}
132 132
133struct cifsFileInfo * 133struct cifsFileInfo *
134cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, 134cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, struct file *file,
135 struct file *file, struct vfsmount *mnt, unsigned int oflags) 135 struct vfsmount *mnt, struct tcon_link *tlink,
136 unsigned int oflags, __u32 oplock)
136{ 137{
137 int oplock = 0;
138 struct cifsFileInfo *pCifsFile; 138 struct cifsFileInfo *pCifsFile;
139 struct cifsInodeInfo *pCifsInode; 139 struct cifsInodeInfo *pCifsInode;
140 struct cifs_sb_info *cifs_sb = CIFS_SB(mnt->mnt_sb);
141 140
142 pCifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); 141 pCifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
143 if (pCifsFile == NULL) 142 if (pCifsFile == NULL)
144 return pCifsFile; 143 return pCifsFile;
145 144
146 if (oplockEnabled)
147 oplock = REQ_OPLOCK;
148
149 pCifsFile->netfid = fileHandle; 145 pCifsFile->netfid = fileHandle;
150 pCifsFile->pid = current->tgid; 146 pCifsFile->pid = current->tgid;
147 pCifsFile->uid = current_fsuid();
151 pCifsFile->pInode = igrab(newinode); 148 pCifsFile->pInode = igrab(newinode);
152 pCifsFile->mnt = mnt; 149 pCifsFile->mnt = mnt;
153 pCifsFile->pfile = file; 150 pCifsFile->pfile = file;
154 pCifsFile->invalidHandle = false; 151 pCifsFile->invalidHandle = false;
155 pCifsFile->closePend = false; 152 pCifsFile->closePend = false;
153 pCifsFile->tlink = cifs_get_tlink(tlink);
156 mutex_init(&pCifsFile->fh_mutex); 154 mutex_init(&pCifsFile->fh_mutex);
157 mutex_init(&pCifsFile->lock_mutex); 155 mutex_init(&pCifsFile->lock_mutex);
158 INIT_LIST_HEAD(&pCifsFile->llist); 156 INIT_LIST_HEAD(&pCifsFile->llist);
@@ -160,7 +158,7 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle,
160 INIT_WORK(&pCifsFile->oplock_break, cifs_oplock_break); 158 INIT_WORK(&pCifsFile->oplock_break, cifs_oplock_break);
161 159
162 write_lock(&GlobalSMBSeslock); 160 write_lock(&GlobalSMBSeslock);
163 list_add(&pCifsFile->tlist, &cifs_sb->tcon->openFileList); 161 list_add(&pCifsFile->tlist, &(tlink_tcon(tlink)->openFileList));
164 pCifsInode = CIFS_I(newinode); 162 pCifsInode = CIFS_I(newinode);
165 if (pCifsInode) { 163 if (pCifsInode) {
166 /* if readable file instance put first in list*/ 164 /* if readable file instance put first in list*/
@@ -193,6 +191,8 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
193 __u32 posix_flags = 0; 191 __u32 posix_flags = 0;
194 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 192 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
195 struct cifs_fattr fattr; 193 struct cifs_fattr fattr;
194 struct tcon_link *tlink;
195 struct cifsTconInfo *tcon;
196 196
197 cFYI(1, "posix open %s", full_path); 197 cFYI(1, "posix open %s", full_path);
198 198
@@ -227,10 +227,20 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
227 posix_flags |= SMB_O_DIRECT; 227 posix_flags |= SMB_O_DIRECT;
228 228
229 mode &= ~current_umask(); 229 mode &= ~current_umask();
230 rc = CIFSPOSIXCreate(xid, cifs_sb->tcon, posix_flags, mode, 230
231 pnetfid, presp_data, poplock, full_path, 231 tlink = cifs_sb_tlink(cifs_sb);
232 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 232 if (IS_ERR(tlink)) {
233 rc = PTR_ERR(tlink);
234 goto posix_open_ret;
235 }
236
237 tcon = tlink_tcon(tlink);
238 rc = CIFSPOSIXCreate(xid, tcon, posix_flags, mode, pnetfid, presp_data,
239 poplock, full_path, cifs_sb->local_nls,
240 cifs_sb->mnt_cifs_flags &
233 CIFS_MOUNT_MAP_SPECIAL_CHR); 241 CIFS_MOUNT_MAP_SPECIAL_CHR);
242 cifs_put_tlink(tlink);
243
234 if (rc) 244 if (rc)
235 goto posix_open_ret; 245 goto posix_open_ret;
236 246
@@ -291,6 +301,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
291 int desiredAccess = GENERIC_READ | GENERIC_WRITE; 301 int desiredAccess = GENERIC_READ | GENERIC_WRITE;
292 __u16 fileHandle; 302 __u16 fileHandle;
293 struct cifs_sb_info *cifs_sb; 303 struct cifs_sb_info *cifs_sb;
304 struct tcon_link *tlink;
294 struct cifsTconInfo *tcon; 305 struct cifsTconInfo *tcon;
295 char *full_path = NULL; 306 char *full_path = NULL;
296 FILE_ALL_INFO *buf = NULL; 307 FILE_ALL_INFO *buf = NULL;
@@ -300,13 +311,12 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
300 xid = GetXid(); 311 xid = GetXid();
301 312
302 cifs_sb = CIFS_SB(inode->i_sb); 313 cifs_sb = CIFS_SB(inode->i_sb);
303 tcon = cifs_sb->tcon; 314 tlink = cifs_sb_tlink(cifs_sb);
304 315 if (IS_ERR(tlink)) {
305 full_path = build_path_from_dentry(direntry); 316 FreeXid(xid);
306 if (full_path == NULL) { 317 return PTR_ERR(tlink);
307 rc = -ENOMEM;
308 goto cifs_create_out;
309 } 318 }
319 tcon = tlink_tcon(tlink);
310 320
311 if (oplockEnabled) 321 if (oplockEnabled)
312 oplock = REQ_OPLOCK; 322 oplock = REQ_OPLOCK;
@@ -316,6 +326,12 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
316 else 326 else
317 oflags = FMODE_READ | SMB_O_CREAT; 327 oflags = FMODE_READ | SMB_O_CREAT;
318 328
329 full_path = build_path_from_dentry(direntry);
330 if (full_path == NULL) {
331 rc = -ENOMEM;
332 goto cifs_create_out;
333 }
334
319 if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) && 335 if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) &&
320 (CIFS_UNIX_POSIX_PATH_OPS_CAP & 336 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
321 le64_to_cpu(tcon->fsUnixInfo.Capability))) { 337 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
@@ -375,7 +391,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
375 if (!tcon->unix_ext && (mode & S_IWUGO) == 0) 391 if (!tcon->unix_ext && (mode & S_IWUGO) == 0)
376 create_options |= CREATE_OPTION_READONLY; 392 create_options |= CREATE_OPTION_READONLY;
377 393
378 if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS) 394 if (tcon->ses->capabilities & CAP_NT_SMBS)
379 rc = CIFSSMBOpen(xid, tcon, full_path, disposition, 395 rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
380 desiredAccess, create_options, 396 desiredAccess, create_options,
381 &fileHandle, &oplock, buf, cifs_sb->local_nls, 397 &fileHandle, &oplock, buf, cifs_sb->local_nls,
@@ -468,7 +484,8 @@ cifs_create_set_dentry:
468 } 484 }
469 485
470 pfile_info = cifs_new_fileinfo(newinode, fileHandle, filp, 486 pfile_info = cifs_new_fileinfo(newinode, fileHandle, filp,
471 nd->path.mnt, oflags); 487 nd->path.mnt, tlink, oflags,
488 oplock);
472 if (pfile_info == NULL) { 489 if (pfile_info == NULL) {
473 fput(filp); 490 fput(filp);
474 CIFSSMBClose(xid, tcon, fileHandle); 491 CIFSSMBClose(xid, tcon, fileHandle);
@@ -481,6 +498,7 @@ cifs_create_set_dentry:
481cifs_create_out: 498cifs_create_out:
482 kfree(buf); 499 kfree(buf);
483 kfree(full_path); 500 kfree(full_path);
501 cifs_put_tlink(tlink);
484 FreeXid(xid); 502 FreeXid(xid);
485 return rc; 503 return rc;
486} 504}
@@ -491,6 +509,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
491 int rc = -EPERM; 509 int rc = -EPERM;
492 int xid; 510 int xid;
493 struct cifs_sb_info *cifs_sb; 511 struct cifs_sb_info *cifs_sb;
512 struct tcon_link *tlink;
494 struct cifsTconInfo *pTcon; 513 struct cifsTconInfo *pTcon;
495 char *full_path = NULL; 514 char *full_path = NULL;
496 struct inode *newinode = NULL; 515 struct inode *newinode = NULL;
@@ -503,10 +522,14 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
503 if (!old_valid_dev(device_number)) 522 if (!old_valid_dev(device_number))
504 return -EINVAL; 523 return -EINVAL;
505 524
506 xid = GetXid();
507
508 cifs_sb = CIFS_SB(inode->i_sb); 525 cifs_sb = CIFS_SB(inode->i_sb);
509 pTcon = cifs_sb->tcon; 526 tlink = cifs_sb_tlink(cifs_sb);
527 if (IS_ERR(tlink))
528 return PTR_ERR(tlink);
529
530 pTcon = tlink_tcon(tlink);
531
532 xid = GetXid();
510 533
511 full_path = build_path_from_dentry(direntry); 534 full_path = build_path_from_dentry(direntry);
512 if (full_path == NULL) { 535 if (full_path == NULL) {
@@ -606,6 +629,7 @@ mknod_out:
606 kfree(full_path); 629 kfree(full_path);
607 kfree(buf); 630 kfree(buf);
608 FreeXid(xid); 631 FreeXid(xid);
632 cifs_put_tlink(tlink);
609 return rc; 633 return rc;
610} 634}
611 635
@@ -619,6 +643,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
619 __u16 fileHandle = 0; 643 __u16 fileHandle = 0;
620 bool posix_open = false; 644 bool posix_open = false;
621 struct cifs_sb_info *cifs_sb; 645 struct cifs_sb_info *cifs_sb;
646 struct tcon_link *tlink;
622 struct cifsTconInfo *pTcon; 647 struct cifsTconInfo *pTcon;
623 struct cifsFileInfo *cfile; 648 struct cifsFileInfo *cfile;
624 struct inode *newInode = NULL; 649 struct inode *newInode = NULL;
@@ -633,7 +658,12 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
633 /* check whether path exists */ 658 /* check whether path exists */
634 659
635 cifs_sb = CIFS_SB(parent_dir_inode->i_sb); 660 cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
636 pTcon = cifs_sb->tcon; 661 tlink = cifs_sb_tlink(cifs_sb);
662 if (IS_ERR(tlink)) {
663 FreeXid(xid);
664 return (struct dentry *)tlink;
665 }
666 pTcon = tlink_tcon(tlink);
637 667
638 /* 668 /*
639 * Don't allow the separator character in a path component. 669 * Don't allow the separator character in a path component.
@@ -644,8 +674,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
644 for (i = 0; i < direntry->d_name.len; i++) 674 for (i = 0; i < direntry->d_name.len; i++)
645 if (direntry->d_name.name[i] == '\\') { 675 if (direntry->d_name.name[i] == '\\') {
646 cFYI(1, "Invalid file name"); 676 cFYI(1, "Invalid file name");
647 FreeXid(xid); 677 rc = -EINVAL;
648 return ERR_PTR(-EINVAL); 678 goto lookup_out;
649 } 679 }
650 } 680 }
651 681
@@ -655,7 +685,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
655 */ 685 */
656 if (nd && (nd->flags & LOOKUP_EXCL)) { 686 if (nd && (nd->flags & LOOKUP_EXCL)) {
657 d_instantiate(direntry, NULL); 687 d_instantiate(direntry, NULL);
658 return NULL; 688 rc = 0;
689 goto lookup_out;
659 } 690 }
660 691
661 /* can not grab the rename sem here since it would 692 /* can not grab the rename sem here since it would
@@ -663,8 +694,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
663 in which we already have the sb rename sem */ 694 in which we already have the sb rename sem */
664 full_path = build_path_from_dentry(direntry); 695 full_path = build_path_from_dentry(direntry);
665 if (full_path == NULL) { 696 if (full_path == NULL) {
666 FreeXid(xid); 697 rc = -ENOMEM;
667 return ERR_PTR(-ENOMEM); 698 goto lookup_out;
668 } 699 }
669 700
670 if (direntry->d_inode != NULL) { 701 if (direntry->d_inode != NULL) {
@@ -728,8 +759,9 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
728 } 759 }
729 760
730 cfile = cifs_new_fileinfo(newInode, fileHandle, filp, 761 cfile = cifs_new_fileinfo(newInode, fileHandle, filp,
731 nd->path.mnt, 762 nd->path.mnt, tlink,
732 nd->intent.open.flags); 763 nd->intent.open.flags,
764 oplock);
733 if (cfile == NULL) { 765 if (cfile == NULL) {
734 fput(filp); 766 fput(filp);
735 CIFSSMBClose(xid, pTcon, fileHandle); 767 CIFSSMBClose(xid, pTcon, fileHandle);
@@ -759,6 +791,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
759 791
760lookup_out: 792lookup_out:
761 kfree(full_path); 793 kfree(full_path);
794 cifs_put_tlink(tlink);
762 FreeXid(xid); 795 FreeXid(xid);
763 return ERR_PTR(rc); 796 return ERR_PTR(rc);
764} 797}
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index de748c652d11..80856f180711 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -165,7 +165,7 @@ psx_client_can_cache:
165 165
166/* all arguments to this function must be checked for validity in caller */ 166/* all arguments to this function must be checked for validity in caller */
167static inline int cifs_open_inode_helper(struct inode *inode, 167static inline int cifs_open_inode_helper(struct inode *inode,
168 struct cifsTconInfo *pTcon, int *oplock, FILE_ALL_INFO *buf, 168 struct cifsTconInfo *pTcon, __u32 oplock, FILE_ALL_INFO *buf,
169 char *full_path, int xid) 169 char *full_path, int xid)
170{ 170{
171 struct cifsInodeInfo *pCifsInode = CIFS_I(inode); 171 struct cifsInodeInfo *pCifsInode = CIFS_I(inode);
@@ -207,11 +207,11 @@ client_can_cache:
207 rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb, 207 rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb,
208 xid, NULL); 208 xid, NULL);
209 209
210 if ((*oplock & 0xF) == OPLOCK_EXCLUSIVE) { 210 if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
211 pCifsInode->clientCanCacheAll = true; 211 pCifsInode->clientCanCacheAll = true;
212 pCifsInode->clientCanCacheRead = true; 212 pCifsInode->clientCanCacheRead = true;
213 cFYI(1, "Exclusive Oplock granted on inode %p", inode); 213 cFYI(1, "Exclusive Oplock granted on inode %p", inode);
214 } else if ((*oplock & 0xF) == OPLOCK_READ) 214 } else if ((oplock & 0xF) == OPLOCK_READ)
215 pCifsInode->clientCanCacheRead = true; 215 pCifsInode->clientCanCacheRead = true;
216 216
217 return rc; 217 return rc;
@@ -224,6 +224,7 @@ int cifs_open(struct inode *inode, struct file *file)
224 __u32 oplock; 224 __u32 oplock;
225 struct cifs_sb_info *cifs_sb; 225 struct cifs_sb_info *cifs_sb;
226 struct cifsTconInfo *tcon; 226 struct cifsTconInfo *tcon;
227 struct tcon_link *tlink;
227 struct cifsFileInfo *pCifsFile = NULL; 228 struct cifsFileInfo *pCifsFile = NULL;
228 struct cifsInodeInfo *pCifsInode; 229 struct cifsInodeInfo *pCifsInode;
229 char *full_path = NULL; 230 char *full_path = NULL;
@@ -235,7 +236,12 @@ int cifs_open(struct inode *inode, struct file *file)
235 xid = GetXid(); 236 xid = GetXid();
236 237
237 cifs_sb = CIFS_SB(inode->i_sb); 238 cifs_sb = CIFS_SB(inode->i_sb);
238 tcon = cifs_sb->tcon; 239 tlink = cifs_sb_tlink(cifs_sb);
240 if (IS_ERR(tlink)) {
241 FreeXid(xid);
242 return PTR_ERR(tlink);
243 }
244 tcon = tlink_tcon(tlink);
239 245
240 pCifsInode = CIFS_I(file->f_path.dentry->d_inode); 246 pCifsInode = CIFS_I(file->f_path.dentry->d_inode);
241 247
@@ -277,7 +283,7 @@ int cifs_open(struct inode *inode, struct file *file)
277 283
278 pCifsFile = cifs_new_fileinfo(inode, netfid, file, 284 pCifsFile = cifs_new_fileinfo(inode, netfid, file,
279 file->f_path.mnt, 285 file->f_path.mnt,
280 oflags); 286 tlink, oflags, oplock);
281 if (pCifsFile == NULL) { 287 if (pCifsFile == NULL) {
282 CIFSSMBClose(xid, tcon, netfid); 288 CIFSSMBClose(xid, tcon, netfid);
283 rc = -ENOMEM; 289 rc = -ENOMEM;
@@ -345,7 +351,7 @@ int cifs_open(struct inode *inode, struct file *file)
345 goto out; 351 goto out;
346 } 352 }
347 353
348 if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS) 354 if (tcon->ses->capabilities & CAP_NT_SMBS)
349 rc = CIFSSMBOpen(xid, tcon, full_path, disposition, 355 rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
350 desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf, 356 desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf,
351 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags 357 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
@@ -365,12 +371,12 @@ int cifs_open(struct inode *inode, struct file *file)
365 goto out; 371 goto out;
366 } 372 }
367 373
368 rc = cifs_open_inode_helper(inode, tcon, &oplock, buf, full_path, xid); 374 rc = cifs_open_inode_helper(inode, tcon, oplock, buf, full_path, xid);
369 if (rc != 0) 375 if (rc != 0)
370 goto out; 376 goto out;
371 377
372 pCifsFile = cifs_new_fileinfo(inode, netfid, file, file->f_path.mnt, 378 pCifsFile = cifs_new_fileinfo(inode, netfid, file, file->f_path.mnt,
373 file->f_flags); 379 tlink, file->f_flags, oplock);
374 if (pCifsFile == NULL) { 380 if (pCifsFile == NULL) {
375 rc = -ENOMEM; 381 rc = -ENOMEM;
376 goto out; 382 goto out;
@@ -402,6 +408,7 @@ out:
402 kfree(buf); 408 kfree(buf);
403 kfree(full_path); 409 kfree(full_path);
404 FreeXid(xid); 410 FreeXid(xid);
411 cifs_put_tlink(tlink);
405 return rc; 412 return rc;
406} 413}
407 414
@@ -461,7 +468,7 @@ static int cifs_reopen_file(struct file *file, bool can_flush)
461 } 468 }
462 469
463 cifs_sb = CIFS_SB(inode->i_sb); 470 cifs_sb = CIFS_SB(inode->i_sb);
464 tcon = cifs_sb->tcon; 471 tcon = tlink_tcon(pCifsFile->tlink);
465 472
466/* can not grab rename sem here because various ops, including 473/* can not grab rename sem here because various ops, including
467 those that already have the rename sem can end up causing writepage 474 those that already have the rename sem can end up causing writepage
@@ -575,7 +582,7 @@ int cifs_close(struct inode *inode, struct file *file)
575 xid = GetXid(); 582 xid = GetXid();
576 583
577 cifs_sb = CIFS_SB(inode->i_sb); 584 cifs_sb = CIFS_SB(inode->i_sb);
578 pTcon = cifs_sb->tcon; 585 pTcon = tlink_tcon(pSMBFile->tlink);
579 if (pSMBFile) { 586 if (pSMBFile) {
580 struct cifsLockInfo *li, *tmp; 587 struct cifsLockInfo *li, *tmp;
581 write_lock(&GlobalSMBSeslock); 588 write_lock(&GlobalSMBSeslock);
@@ -653,11 +660,7 @@ int cifs_closedir(struct inode *inode, struct file *file)
653 xid = GetXid(); 660 xid = GetXid();
654 661
655 if (pCFileStruct) { 662 if (pCFileStruct) {
656 struct cifsTconInfo *pTcon; 663 struct cifsTconInfo *pTcon = tlink_tcon(pCFileStruct->tlink);
657 struct cifs_sb_info *cifs_sb =
658 CIFS_SB(file->f_path.dentry->d_sb);
659
660 pTcon = cifs_sb->tcon;
661 664
662 cFYI(1, "Freeing private data in close dir"); 665 cFYI(1, "Freeing private data in close dir");
663 write_lock(&GlobalSMBSeslock); 666 write_lock(&GlobalSMBSeslock);
@@ -681,6 +684,7 @@ int cifs_closedir(struct inode *inode, struct file *file)
681 else 684 else
682 cifs_buf_release(ptmp); 685 cifs_buf_release(ptmp);
683 } 686 }
687 cifs_put_tlink(pCFileStruct->tlink);
684 kfree(file->private_data); 688 kfree(file->private_data);
685 file->private_data = NULL; 689 file->private_data = NULL;
686 } 690 }
@@ -767,7 +771,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
767 cFYI(1, "Unknown type of lock"); 771 cFYI(1, "Unknown type of lock");
768 772
769 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 773 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
770 tcon = cifs_sb->tcon; 774 tcon = tlink_tcon(((struct cifsFileInfo *)file->private_data)->tlink);
771 775
772 if (file->private_data == NULL) { 776 if (file->private_data == NULL) {
773 rc = -EBADF; 777 rc = -EBADF;
@@ -960,14 +964,14 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
960 964
961 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 965 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
962 966
963 pTcon = cifs_sb->tcon;
964
965 /* cFYI(1, " write %d bytes to offset %lld of %s", write_size, 967 /* cFYI(1, " write %d bytes to offset %lld of %s", write_size,
966 *poffset, file->f_path.dentry->d_name.name); */ 968 *poffset, file->f_path.dentry->d_name.name); */
967 969
968 if (file->private_data == NULL) 970 if (file->private_data == NULL)
969 return -EBADF; 971 return -EBADF;
972
970 open_file = file->private_data; 973 open_file = file->private_data;
974 pTcon = tlink_tcon(open_file->tlink);
971 975
972 rc = generic_write_checks(file, poffset, &write_size, 0); 976 rc = generic_write_checks(file, poffset, &write_size, 0);
973 if (rc) 977 if (rc)
@@ -1062,14 +1066,13 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
1062 1066
1063 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 1067 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
1064 1068
1065 pTcon = cifs_sb->tcon;
1066
1067 cFYI(1, "write %zd bytes to offset %lld of %s", write_size, 1069 cFYI(1, "write %zd bytes to offset %lld of %s", write_size,
1068 *poffset, file->f_path.dentry->d_name.name); 1070 *poffset, file->f_path.dentry->d_name.name);
1069 1071
1070 if (file->private_data == NULL) 1072 if (file->private_data == NULL)
1071 return -EBADF; 1073 return -EBADF;
1072 open_file = file->private_data; 1074 open_file = file->private_data;
1075 pTcon = tlink_tcon(open_file->tlink);
1073 1076
1074 xid = GetXid(); 1077 xid = GetXid();
1075 1078
@@ -1165,9 +1168,15 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
1165} 1168}
1166 1169
1167#ifdef CONFIG_CIFS_EXPERIMENTAL 1170#ifdef CONFIG_CIFS_EXPERIMENTAL
1168struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode) 1171struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
1172 bool fsuid_only)
1169{ 1173{
1170 struct cifsFileInfo *open_file = NULL; 1174 struct cifsFileInfo *open_file = NULL;
1175 struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb);
1176
1177 /* only filter by fsuid on multiuser mounts */
1178 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
1179 fsuid_only = false;
1171 1180
1172 read_lock(&GlobalSMBSeslock); 1181 read_lock(&GlobalSMBSeslock);
1173 /* we could simply get the first_list_entry since write-only entries 1182 /* we could simply get the first_list_entry since write-only entries
@@ -1176,6 +1185,8 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode)
1176 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { 1185 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
1177 if (open_file->closePend) 1186 if (open_file->closePend)
1178 continue; 1187 continue;
1188 if (fsuid_only && open_file->uid != current_fsuid())
1189 continue;
1179 if (open_file->pfile && ((open_file->pfile->f_flags & O_RDWR) || 1190 if (open_file->pfile && ((open_file->pfile->f_flags & O_RDWR) ||
1180 (open_file->pfile->f_flags & O_RDONLY))) { 1191 (open_file->pfile->f_flags & O_RDONLY))) {
1181 if (!open_file->invalidHandle) { 1192 if (!open_file->invalidHandle) {
@@ -1195,9 +1206,11 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode)
1195} 1206}
1196#endif 1207#endif
1197 1208
1198struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) 1209struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,
1210 bool fsuid_only)
1199{ 1211{
1200 struct cifsFileInfo *open_file; 1212 struct cifsFileInfo *open_file;
1213 struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb);
1201 bool any_available = false; 1214 bool any_available = false;
1202 int rc; 1215 int rc;
1203 1216
@@ -1211,13 +1224,19 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
1211 return NULL; 1224 return NULL;
1212 } 1225 }
1213 1226
1227 /* only filter by fsuid on multiuser mounts */
1228 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
1229 fsuid_only = false;
1230
1214 read_lock(&GlobalSMBSeslock); 1231 read_lock(&GlobalSMBSeslock);
1215refind_writable: 1232refind_writable:
1216 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { 1233 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
1217 if (open_file->closePend || 1234 if (open_file->closePend)
1218 (!any_available && open_file->pid != current->tgid)) 1235 continue;
1236 if (!any_available && open_file->pid != current->tgid)
1237 continue;
1238 if (fsuid_only && open_file->uid != current_fsuid())
1219 continue; 1239 continue;
1220
1221 if (open_file->pfile && 1240 if (open_file->pfile &&
1222 ((open_file->pfile->f_flags & O_RDWR) || 1241 ((open_file->pfile->f_flags & O_RDWR) ||
1223 (open_file->pfile->f_flags & O_WRONLY))) { 1242 (open_file->pfile->f_flags & O_WRONLY))) {
@@ -1284,7 +1303,6 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
1284 int rc = -EFAULT; 1303 int rc = -EFAULT;
1285 int bytes_written = 0; 1304 int bytes_written = 0;
1286 struct cifs_sb_info *cifs_sb; 1305 struct cifs_sb_info *cifs_sb;
1287 struct cifsTconInfo *pTcon;
1288 struct inode *inode; 1306 struct inode *inode;
1289 struct cifsFileInfo *open_file; 1307 struct cifsFileInfo *open_file;
1290 1308
@@ -1293,7 +1311,6 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
1293 1311
1294 inode = page->mapping->host; 1312 inode = page->mapping->host;
1295 cifs_sb = CIFS_SB(inode->i_sb); 1313 cifs_sb = CIFS_SB(inode->i_sb);
1296 pTcon = cifs_sb->tcon;
1297 1314
1298 offset += (loff_t)from; 1315 offset += (loff_t)from;
1299 write_data = kmap(page); 1316 write_data = kmap(page);
@@ -1314,7 +1331,7 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
1314 if (mapping->host->i_size - offset < (loff_t)to) 1331 if (mapping->host->i_size - offset < (loff_t)to)
1315 to = (unsigned)(mapping->host->i_size - offset); 1332 to = (unsigned)(mapping->host->i_size - offset);
1316 1333
1317 open_file = find_writable_file(CIFS_I(mapping->host)); 1334 open_file = find_writable_file(CIFS_I(mapping->host), false);
1318 if (open_file) { 1335 if (open_file) {
1319 bytes_written = cifs_write(open_file->pfile, write_data, 1336 bytes_written = cifs_write(open_file->pfile, write_data,
1320 to-from, &offset); 1337 to-from, &offset);
@@ -1352,6 +1369,7 @@ static int cifs_writepages(struct address_space *mapping,
1352 int nr_pages; 1369 int nr_pages;
1353 __u64 offset = 0; 1370 __u64 offset = 0;
1354 struct cifsFileInfo *open_file; 1371 struct cifsFileInfo *open_file;
1372 struct cifsTconInfo *tcon;
1355 struct cifsInodeInfo *cifsi = CIFS_I(mapping->host); 1373 struct cifsInodeInfo *cifsi = CIFS_I(mapping->host);
1356 struct page *page; 1374 struct page *page;
1357 struct pagevec pvec; 1375 struct pagevec pvec;
@@ -1359,6 +1377,15 @@ static int cifs_writepages(struct address_space *mapping,
1359 int scanned = 0; 1377 int scanned = 0;
1360 int xid, long_op; 1378 int xid, long_op;
1361 1379
1380 /*
1381 * BB: Is this meaningful for a non-block-device file system?
1382 * If it is, we should test it again after we do I/O
1383 */
1384 if (wbc->nonblocking && bdi_write_congested(bdi)) {
1385 wbc->encountered_congestion = 1;
1386 return 0;
1387 }
1388
1362 cifs_sb = CIFS_SB(mapping->host->i_sb); 1389 cifs_sb = CIFS_SB(mapping->host->i_sb);
1363 1390
1364 /* 1391 /*
@@ -1368,27 +1395,29 @@ static int cifs_writepages(struct address_space *mapping,
1368 if (cifs_sb->wsize < PAGE_CACHE_SIZE) 1395 if (cifs_sb->wsize < PAGE_CACHE_SIZE)
1369 return generic_writepages(mapping, wbc); 1396 return generic_writepages(mapping, wbc);
1370 1397
1371 if ((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->server))
1372 if (cifs_sb->tcon->ses->server->secMode &
1373 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
1374 if (!experimEnabled)
1375 return generic_writepages(mapping, wbc);
1376
1377 iov = kmalloc(32 * sizeof(struct kvec), GFP_KERNEL); 1398 iov = kmalloc(32 * sizeof(struct kvec), GFP_KERNEL);
1378 if (iov == NULL) 1399 if (iov == NULL)
1379 return generic_writepages(mapping, wbc); 1400 return generic_writepages(mapping, wbc);
1380 1401
1381
1382 /* 1402 /*
1383 * BB: Is this meaningful for a non-block-device file system? 1403 * if there's no open file, then this is likely to fail too,
1384 * If it is, we should test it again after we do I/O 1404 * but it'll at least handle the return. Maybe it should be
1405 * a BUG() instead?
1385 */ 1406 */
1386 if (wbc->nonblocking && bdi_write_congested(bdi)) { 1407 open_file = find_writable_file(CIFS_I(mapping->host), false);
1387 wbc->encountered_congestion = 1; 1408 if (!open_file) {
1388 kfree(iov); 1409 kfree(iov);
1389 return 0; 1410 return generic_writepages(mapping, wbc);
1390 } 1411 }
1391 1412
1413 tcon = tlink_tcon(open_file->tlink);
1414 if (!experimEnabled && tcon->ses->server->secMode &
1415 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
1416 cifsFileInfo_put(open_file);
1417 return generic_writepages(mapping, wbc);
1418 }
1419 cifsFileInfo_put(open_file);
1420
1392 xid = GetXid(); 1421 xid = GetXid();
1393 1422
1394 pagevec_init(&pvec, 0); 1423 pagevec_init(&pvec, 0);
@@ -1492,38 +1521,34 @@ retry:
1492 break; 1521 break;
1493 } 1522 }
1494 if (n_iov) { 1523 if (n_iov) {
1495 /* Search for a writable handle every time we call 1524 open_file = find_writable_file(CIFS_I(mapping->host),
1496 * CIFSSMBWrite2. We can't rely on the last handle 1525 false);
1497 * we used to still be valid
1498 */
1499 open_file = find_writable_file(CIFS_I(mapping->host));
1500 if (!open_file) { 1526 if (!open_file) {
1501 cERROR(1, "No writable handles for inode"); 1527 cERROR(1, "No writable handles for inode");
1502 rc = -EBADF; 1528 rc = -EBADF;
1503 } else { 1529 } else {
1504 long_op = cifs_write_timeout(cifsi, offset); 1530 long_op = cifs_write_timeout(cifsi, offset);
1505 rc = CIFSSMBWrite2(xid, cifs_sb->tcon, 1531 rc = CIFSSMBWrite2(xid, tcon, open_file->netfid,
1506 open_file->netfid,
1507 bytes_to_write, offset, 1532 bytes_to_write, offset,
1508 &bytes_written, iov, n_iov, 1533 &bytes_written, iov, n_iov,
1509 long_op); 1534 long_op);
1510 cifsFileInfo_put(open_file); 1535 cifsFileInfo_put(open_file);
1511 cifs_update_eof(cifsi, offset, bytes_written); 1536 cifs_update_eof(cifsi, offset, bytes_written);
1537 }
1512 1538
1513 if (rc || bytes_written < bytes_to_write) { 1539 if (rc || bytes_written < bytes_to_write) {
1514 cERROR(1, "Write2 ret %d, wrote %d", 1540 cERROR(1, "Write2 ret %d, wrote %d",
1515 rc, bytes_written); 1541 rc, bytes_written);
1516 /* BB what if continued retry is 1542 /* BB what if continued retry is
1517 requested via mount flags? */ 1543 requested via mount flags? */
1518 if (rc == -ENOSPC) 1544 if (rc == -ENOSPC)
1519 set_bit(AS_ENOSPC, &mapping->flags); 1545 set_bit(AS_ENOSPC, &mapping->flags);
1520 else 1546 else
1521 set_bit(AS_EIO, &mapping->flags); 1547 set_bit(AS_EIO, &mapping->flags);
1522 } else { 1548 } else {
1523 cifs_stats_bytes_written(cifs_sb->tcon, 1549 cifs_stats_bytes_written(tcon, bytes_written);
1524 bytes_written);
1525 }
1526 } 1550 }
1551
1527 for (i = 0; i < n_iov; i++) { 1552 for (i = 0; i < n_iov; i++) {
1528 page = pvec.pages[first + i]; 1553 page = pvec.pages[first + i];
1529 /* Should we also set page error on 1554 /* Should we also set page error on
@@ -1665,7 +1690,7 @@ int cifs_fsync(struct file *file, int datasync)
1665 if (rc == 0) { 1690 if (rc == 0) {
1666 rc = CIFS_I(inode)->write_behind_rc; 1691 rc = CIFS_I(inode)->write_behind_rc;
1667 CIFS_I(inode)->write_behind_rc = 0; 1692 CIFS_I(inode)->write_behind_rc = 0;
1668 tcon = CIFS_SB(inode->i_sb)->tcon; 1693 tcon = tlink_tcon(smbfile->tlink);
1669 if (!rc && tcon && smbfile && 1694 if (!rc && tcon && smbfile &&
1670 !(CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) 1695 !(CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC))
1671 rc = CIFSSMBFlush(xid, tcon, smbfile->netfid); 1696 rc = CIFSSMBFlush(xid, tcon, smbfile->netfid);
@@ -1750,7 +1775,6 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
1750 1775
1751 xid = GetXid(); 1776 xid = GetXid();
1752 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 1777 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
1753 pTcon = cifs_sb->tcon;
1754 1778
1755 if (file->private_data == NULL) { 1779 if (file->private_data == NULL) {
1756 rc = -EBADF; 1780 rc = -EBADF;
@@ -1758,6 +1782,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
1758 return rc; 1782 return rc;
1759 } 1783 }
1760 open_file = file->private_data; 1784 open_file = file->private_data;
1785 pTcon = tlink_tcon(open_file->tlink);
1761 1786
1762 if ((file->f_flags & O_ACCMODE) == O_WRONLY) 1787 if ((file->f_flags & O_ACCMODE) == O_WRONLY)
1763 cFYI(1, "attempting read on write only file instance"); 1788 cFYI(1, "attempting read on write only file instance");
@@ -1831,7 +1856,6 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
1831 1856
1832 xid = GetXid(); 1857 xid = GetXid();
1833 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 1858 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
1834 pTcon = cifs_sb->tcon;
1835 1859
1836 if (file->private_data == NULL) { 1860 if (file->private_data == NULL) {
1837 rc = -EBADF; 1861 rc = -EBADF;
@@ -1839,6 +1863,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
1839 return rc; 1863 return rc;
1840 } 1864 }
1841 open_file = file->private_data; 1865 open_file = file->private_data;
1866 pTcon = tlink_tcon(open_file->tlink);
1842 1867
1843 if ((file->f_flags & O_ACCMODE) == O_WRONLY) 1868 if ((file->f_flags & O_ACCMODE) == O_WRONLY)
1844 cFYI(1, "attempting read on write only file instance"); 1869 cFYI(1, "attempting read on write only file instance");
@@ -1974,7 +1999,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1974 } 1999 }
1975 open_file = file->private_data; 2000 open_file = file->private_data;
1976 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 2001 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
1977 pTcon = cifs_sb->tcon; 2002 pTcon = tlink_tcon(open_file->tlink);
1978 2003
1979 /* 2004 /*
1980 * Reads as many pages as possible from fscache. Returns -ENOBUFS 2005 * Reads as many pages as possible from fscache. Returns -ENOBUFS
@@ -2312,7 +2337,6 @@ void cifs_oplock_break(struct work_struct *work)
2312 oplock_break); 2337 oplock_break);
2313 struct inode *inode = cfile->pInode; 2338 struct inode *inode = cfile->pInode;
2314 struct cifsInodeInfo *cinode = CIFS_I(inode); 2339 struct cifsInodeInfo *cinode = CIFS_I(inode);
2315 struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->mnt->mnt_sb);
2316 int rc, waitrc = 0; 2340 int rc, waitrc = 0;
2317 2341
2318 if (inode && S_ISREG(inode->i_mode)) { 2342 if (inode && S_ISREG(inode->i_mode)) {
@@ -2339,8 +2363,8 @@ void cifs_oplock_break(struct work_struct *work)
2339 * disconnected since oplock already released by the server 2363 * disconnected since oplock already released by the server
2340 */ 2364 */
2341 if (!cfile->closePend && !cfile->oplock_break_cancelled) { 2365 if (!cfile->closePend && !cfile->oplock_break_cancelled) {
2342 rc = CIFSSMBLock(0, cifs_sb->tcon, cfile->netfid, 0, 0, 0, 0, 2366 rc = CIFSSMBLock(0, tlink_tcon(cfile->tlink), cfile->netfid, 0,
2343 LOCKING_ANDX_OPLOCK_RELEASE, false); 2367 0, 0, 0, LOCKING_ANDX_OPLOCK_RELEASE, false);
2344 cFYI(1, "Oplock release rc = %d", rc); 2368 cFYI(1, "Oplock release rc = %d", rc);
2345 } 2369 }
2346 2370
diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c
index 9f3f5c4be161..a2ad94efcfe6 100644
--- a/fs/cifs/fscache.c
+++ b/fs/cifs/fscache.c
@@ -62,15 +62,15 @@ static void cifs_fscache_enable_inode_cookie(struct inode *inode)
62{ 62{
63 struct cifsInodeInfo *cifsi = CIFS_I(inode); 63 struct cifsInodeInfo *cifsi = CIFS_I(inode);
64 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 64 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
65 struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
65 66
66 if (cifsi->fscache) 67 if (cifsi->fscache)
67 return; 68 return;
68 69
69 cifsi->fscache = fscache_acquire_cookie(cifs_sb->tcon->fscache, 70 cifsi->fscache = fscache_acquire_cookie(tcon->fscache,
70 &cifs_fscache_inode_object_def, 71 &cifs_fscache_inode_object_def, cifsi);
71 cifsi); 72 cFYI(1, "CIFS: got FH cookie (0x%p/0x%p)", tcon->fscache,
72 cFYI(1, "CIFS: got FH cookie (0x%p/0x%p)", 73 cifsi->fscache);
73 cifs_sb->tcon->fscache, cifsi->fscache);
74} 74}
75 75
76void cifs_fscache_release_inode_cookie(struct inode *inode) 76void cifs_fscache_release_inode_cookie(struct inode *inode)
@@ -117,7 +117,8 @@ void cifs_fscache_reset_inode_cookie(struct inode *inode)
117 /* retire the current fscache cache and get a new one */ 117 /* retire the current fscache cache and get a new one */
118 fscache_relinquish_cookie(cifsi->fscache, 1); 118 fscache_relinquish_cookie(cifsi->fscache, 1);
119 119
120 cifsi->fscache = fscache_acquire_cookie(cifs_sb->tcon->fscache, 120 cifsi->fscache = fscache_acquire_cookie(
121 cifs_sb_master_tcon(cifs_sb)->fscache,
121 &cifs_fscache_inode_object_def, 122 &cifs_fscache_inode_object_def,
122 cifsi); 123 cifsi);
123 cFYI(1, "CIFS: new cookie 0x%p oldcookie 0x%p", 124 cFYI(1, "CIFS: new cookie 0x%p oldcookie 0x%p",
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 53cce8cc2224..f629159be4e0 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -52,7 +52,7 @@ static void cifs_set_ops(struct inode *inode, const bool is_dfs_referral)
52 52
53 53
54 /* check if server can support readpages */ 54 /* check if server can support readpages */
55 if (cifs_sb->tcon->ses->server->maxBuf < 55 if (cifs_sb_master_tcon(cifs_sb)->ses->server->maxBuf <
56 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE) 56 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)
57 inode->i_data.a_ops = &cifs_addr_ops_smallbuf; 57 inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
58 else 58 else
@@ -288,8 +288,8 @@ int cifs_get_file_info_unix(struct file *filp)
288 struct cifs_fattr fattr; 288 struct cifs_fattr fattr;
289 struct inode *inode = filp->f_path.dentry->d_inode; 289 struct inode *inode = filp->f_path.dentry->d_inode;
290 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 290 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
291 struct cifsTconInfo *tcon = cifs_sb->tcon;
292 struct cifsFileInfo *cfile = filp->private_data; 291 struct cifsFileInfo *cfile = filp->private_data;
292 struct cifsTconInfo *tcon = tlink_tcon(cfile->tlink);
293 293
294 xid = GetXid(); 294 xid = GetXid();
295 rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data); 295 rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data);
@@ -313,15 +313,21 @@ int cifs_get_inode_info_unix(struct inode **pinode,
313 FILE_UNIX_BASIC_INFO find_data; 313 FILE_UNIX_BASIC_INFO find_data;
314 struct cifs_fattr fattr; 314 struct cifs_fattr fattr;
315 struct cifsTconInfo *tcon; 315 struct cifsTconInfo *tcon;
316 struct tcon_link *tlink;
316 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 317 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
317 318
318 tcon = cifs_sb->tcon;
319 cFYI(1, "Getting info on %s", full_path); 319 cFYI(1, "Getting info on %s", full_path);
320 320
321 tlink = cifs_sb_tlink(cifs_sb);
322 if (IS_ERR(tlink))
323 return PTR_ERR(tlink);
324 tcon = tlink_tcon(tlink);
325
321 /* could have done a find first instead but this returns more info */ 326 /* could have done a find first instead but this returns more info */
322 rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data, 327 rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data,
323 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 328 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
324 CIFS_MOUNT_MAP_SPECIAL_CHR); 329 CIFS_MOUNT_MAP_SPECIAL_CHR);
330 cifs_put_tlink(tlink);
325 331
326 if (!rc) { 332 if (!rc) {
327 cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb); 333 cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
@@ -332,6 +338,13 @@ int cifs_get_inode_info_unix(struct inode **pinode,
332 return rc; 338 return rc;
333 } 339 }
334 340
341 /* check for Minshall+French symlinks */
342 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
343 int tmprc = CIFSCheckMFSymlink(&fattr, full_path, cifs_sb, xid);
344 if (tmprc)
345 cFYI(1, "CIFSCheckMFSymlink: %d", tmprc);
346 }
347
335 if (*pinode == NULL) { 348 if (*pinode == NULL) {
336 /* get new inode */ 349 /* get new inode */
337 cifs_fill_uniqueid(sb, &fattr); 350 cifs_fill_uniqueid(sb, &fattr);
@@ -353,7 +366,8 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
353 int rc; 366 int rc;
354 int oplock = 0; 367 int oplock = 0;
355 __u16 netfid; 368 __u16 netfid;
356 struct cifsTconInfo *pTcon = cifs_sb->tcon; 369 struct tcon_link *tlink;
370 struct cifsTconInfo *tcon;
357 char buf[24]; 371 char buf[24];
358 unsigned int bytes_read; 372 unsigned int bytes_read;
359 char *pbuf; 373 char *pbuf;
@@ -372,7 +386,12 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
372 return -EINVAL; /* EOPNOTSUPP? */ 386 return -EINVAL; /* EOPNOTSUPP? */
373 } 387 }
374 388
375 rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ, 389 tlink = cifs_sb_tlink(cifs_sb);
390 if (IS_ERR(tlink))
391 return PTR_ERR(tlink);
392 tcon = tlink_tcon(tlink);
393
394 rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, GENERIC_READ,
376 CREATE_NOT_DIR, &netfid, &oplock, NULL, 395 CREATE_NOT_DIR, &netfid, &oplock, NULL,
377 cifs_sb->local_nls, 396 cifs_sb->local_nls,
378 cifs_sb->mnt_cifs_flags & 397 cifs_sb->mnt_cifs_flags &
@@ -380,7 +399,7 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
380 if (rc == 0) { 399 if (rc == 0) {
381 int buf_type = CIFS_NO_BUFFER; 400 int buf_type = CIFS_NO_BUFFER;
382 /* Read header */ 401 /* Read header */
383 rc = CIFSSMBRead(xid, pTcon, netfid, 402 rc = CIFSSMBRead(xid, tcon, netfid,
384 24 /* length */, 0 /* offset */, 403 24 /* length */, 0 /* offset */,
385 &bytes_read, &pbuf, &buf_type); 404 &bytes_read, &pbuf, &buf_type);
386 if ((rc == 0) && (bytes_read >= 8)) { 405 if ((rc == 0) && (bytes_read >= 8)) {
@@ -422,8 +441,9 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
422 fattr->cf_dtype = DT_REG; 441 fattr->cf_dtype = DT_REG;
423 rc = -EOPNOTSUPP; /* or some unknown SFU type */ 442 rc = -EOPNOTSUPP; /* or some unknown SFU type */
424 } 443 }
425 CIFSSMBClose(xid, pTcon, netfid); 444 CIFSSMBClose(xid, tcon, netfid);
426 } 445 }
446 cifs_put_tlink(tlink);
427 return rc; 447 return rc;
428} 448}
429 449
@@ -441,11 +461,19 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
441 ssize_t rc; 461 ssize_t rc;
442 char ea_value[4]; 462 char ea_value[4];
443 __u32 mode; 463 __u32 mode;
464 struct tcon_link *tlink;
465 struct cifsTconInfo *tcon;
466
467 tlink = cifs_sb_tlink(cifs_sb);
468 if (IS_ERR(tlink))
469 return PTR_ERR(tlink);
470 tcon = tlink_tcon(tlink);
444 471
445 rc = CIFSSMBQAllEAs(xid, cifs_sb->tcon, path, "SETFILEBITS", 472 rc = CIFSSMBQAllEAs(xid, tcon, path, "SETFILEBITS",
446 ea_value, 4 /* size of buf */, cifs_sb->local_nls, 473 ea_value, 4 /* size of buf */, cifs_sb->local_nls,
447 cifs_sb->mnt_cifs_flags & 474 cifs_sb->mnt_cifs_flags &
448 CIFS_MOUNT_MAP_SPECIAL_CHR); 475 CIFS_MOUNT_MAP_SPECIAL_CHR);
476 cifs_put_tlink(tlink);
449 if (rc < 0) 477 if (rc < 0)
450 return (int)rc; 478 return (int)rc;
451 else if (rc > 3) { 479 else if (rc > 3) {
@@ -468,6 +496,8 @@ static void
468cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, 496cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
469 struct cifs_sb_info *cifs_sb, bool adjust_tz) 497 struct cifs_sb_info *cifs_sb, bool adjust_tz)
470{ 498{
499 struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
500
471 memset(fattr, 0, sizeof(*fattr)); 501 memset(fattr, 0, sizeof(*fattr));
472 fattr->cf_cifsattrs = le32_to_cpu(info->Attributes); 502 fattr->cf_cifsattrs = le32_to_cpu(info->Attributes);
473 if (info->DeletePending) 503 if (info->DeletePending)
@@ -482,8 +512,8 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
482 fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime); 512 fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime);
483 513
484 if (adjust_tz) { 514 if (adjust_tz) {
485 fattr->cf_ctime.tv_sec += cifs_sb->tcon->ses->server->timeAdj; 515 fattr->cf_ctime.tv_sec += tcon->ses->server->timeAdj;
486 fattr->cf_mtime.tv_sec += cifs_sb->tcon->ses->server->timeAdj; 516 fattr->cf_mtime.tv_sec += tcon->ses->server->timeAdj;
487 } 517 }
488 518
489 fattr->cf_eof = le64_to_cpu(info->EndOfFile); 519 fattr->cf_eof = le64_to_cpu(info->EndOfFile);
@@ -515,8 +545,8 @@ int cifs_get_file_info(struct file *filp)
515 struct cifs_fattr fattr; 545 struct cifs_fattr fattr;
516 struct inode *inode = filp->f_path.dentry->d_inode; 546 struct inode *inode = filp->f_path.dentry->d_inode;
517 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 547 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
518 struct cifsTconInfo *tcon = cifs_sb->tcon;
519 struct cifsFileInfo *cfile = filp->private_data; 548 struct cifsFileInfo *cfile = filp->private_data;
549 struct cifsTconInfo *tcon = tlink_tcon(cfile->tlink);
520 550
521 xid = GetXid(); 551 xid = GetXid();
522 rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data); 552 rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data);
@@ -554,26 +584,33 @@ int cifs_get_inode_info(struct inode **pinode,
554{ 584{
555 int rc = 0, tmprc; 585 int rc = 0, tmprc;
556 struct cifsTconInfo *pTcon; 586 struct cifsTconInfo *pTcon;
587 struct tcon_link *tlink;
557 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 588 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
558 char *buf = NULL; 589 char *buf = NULL;
559 bool adjustTZ = false; 590 bool adjustTZ = false;
560 struct cifs_fattr fattr; 591 struct cifs_fattr fattr;
561 592
562 pTcon = cifs_sb->tcon; 593 tlink = cifs_sb_tlink(cifs_sb);
594 if (IS_ERR(tlink))
595 return PTR_ERR(tlink);
596 pTcon = tlink_tcon(tlink);
597
563 cFYI(1, "Getting info on %s", full_path); 598 cFYI(1, "Getting info on %s", full_path);
564 599
565 if ((pfindData == NULL) && (*pinode != NULL)) { 600 if ((pfindData == NULL) && (*pinode != NULL)) {
566 if (CIFS_I(*pinode)->clientCanCacheRead) { 601 if (CIFS_I(*pinode)->clientCanCacheRead) {
567 cFYI(1, "No need to revalidate cached inode sizes"); 602 cFYI(1, "No need to revalidate cached inode sizes");
568 return rc; 603 goto cgii_exit;
569 } 604 }
570 } 605 }
571 606
572 /* if file info not passed in then get it from server */ 607 /* if file info not passed in then get it from server */
573 if (pfindData == NULL) { 608 if (pfindData == NULL) {
574 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); 609 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
575 if (buf == NULL) 610 if (buf == NULL) {
576 return -ENOMEM; 611 rc = -ENOMEM;
612 goto cgii_exit;
613 }
577 pfindData = (FILE_ALL_INFO *)buf; 614 pfindData = (FILE_ALL_INFO *)buf;
578 615
579 /* could do find first instead but this returns more info */ 616 /* could do find first instead but this returns more info */
@@ -661,6 +698,13 @@ int cifs_get_inode_info(struct inode **pinode,
661 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) 698 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
662 cifs_sfu_mode(&fattr, full_path, cifs_sb, xid); 699 cifs_sfu_mode(&fattr, full_path, cifs_sb, xid);
663 700
701 /* check for Minshall+French symlinks */
702 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
703 tmprc = CIFSCheckMFSymlink(&fattr, full_path, cifs_sb, xid);
704 if (tmprc)
705 cFYI(1, "CIFSCheckMFSymlink: %d", tmprc);
706 }
707
664 if (!*pinode) { 708 if (!*pinode) {
665 *pinode = cifs_iget(sb, &fattr); 709 *pinode = cifs_iget(sb, &fattr);
666 if (!*pinode) 710 if (!*pinode)
@@ -671,6 +715,7 @@ int cifs_get_inode_info(struct inode **pinode,
671 715
672cgii_exit: 716cgii_exit:
673 kfree(buf); 717 kfree(buf);
718 cifs_put_tlink(tlink);
674 return rc; 719 return rc;
675} 720}
676 721
@@ -683,6 +728,7 @@ char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb)
683 int pplen = cifs_sb->prepathlen; 728 int pplen = cifs_sb->prepathlen;
684 int dfsplen; 729 int dfsplen;
685 char *full_path = NULL; 730 char *full_path = NULL;
731 struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
686 732
687 /* if no prefix path, simply set path to the root of share to "" */ 733 /* if no prefix path, simply set path to the root of share to "" */
688 if (pplen == 0) { 734 if (pplen == 0) {
@@ -692,8 +738,8 @@ char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb)
692 return full_path; 738 return full_path;
693 } 739 }
694 740
695 if (cifs_sb->tcon && (cifs_sb->tcon->Flags & SMB_SHARE_IS_IN_DFS)) 741 if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
696 dfsplen = strnlen(cifs_sb->tcon->treeName, MAX_TREE_SIZE + 1); 742 dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
697 else 743 else
698 dfsplen = 0; 744 dfsplen = 0;
699 745
@@ -702,7 +748,7 @@ char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb)
702 return full_path; 748 return full_path;
703 749
704 if (dfsplen) { 750 if (dfsplen) {
705 strncpy(full_path, cifs_sb->tcon->treeName, dfsplen); 751 strncpy(full_path, tcon->treeName, dfsplen);
706 /* switch slash direction in prepath depending on whether 752 /* switch slash direction in prepath depending on whether
707 * windows or posix style path names 753 * windows or posix style path names
708 */ 754 */
@@ -818,18 +864,18 @@ retry_iget5_locked:
818struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino) 864struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
819{ 865{
820 int xid; 866 int xid;
821 struct cifs_sb_info *cifs_sb; 867 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
822 struct inode *inode = NULL; 868 struct inode *inode = NULL;
823 long rc; 869 long rc;
824 char *full_path; 870 char *full_path;
871 struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
825 872
826 cifs_sb = CIFS_SB(sb);
827 full_path = cifs_build_path_to_root(cifs_sb); 873 full_path = cifs_build_path_to_root(cifs_sb);
828 if (full_path == NULL) 874 if (full_path == NULL)
829 return ERR_PTR(-ENOMEM); 875 return ERR_PTR(-ENOMEM);
830 876
831 xid = GetXid(); 877 xid = GetXid();
832 if (cifs_sb->tcon->unix_ext) 878 if (tcon->unix_ext)
833 rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid); 879 rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
834 else 880 else
835 rc = cifs_get_inode_info(&inode, full_path, NULL, sb, 881 rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
@@ -840,10 +886,10 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
840 886
841#ifdef CONFIG_CIFS_FSCACHE 887#ifdef CONFIG_CIFS_FSCACHE
842 /* populate tcon->resource_id */ 888 /* populate tcon->resource_id */
843 cifs_sb->tcon->resource_id = CIFS_I(inode)->uniqueid; 889 tcon->resource_id = CIFS_I(inode)->uniqueid;
844#endif 890#endif
845 891
846 if (rc && cifs_sb->tcon->ipc) { 892 if (rc && tcon->ipc) {
847 cFYI(1, "ipc connection - fake read inode"); 893 cFYI(1, "ipc connection - fake read inode");
848 inode->i_mode |= S_IFDIR; 894 inode->i_mode |= S_IFDIR;
849 inode->i_nlink = 2; 895 inode->i_nlink = 2;
@@ -879,7 +925,8 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
879 struct cifsFileInfo *open_file; 925 struct cifsFileInfo *open_file;
880 struct cifsInodeInfo *cifsInode = CIFS_I(inode); 926 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
881 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 927 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
882 struct cifsTconInfo *pTcon = cifs_sb->tcon; 928 struct tcon_link *tlink = NULL;
929 struct cifsTconInfo *pTcon;
883 FILE_BASIC_INFO info_buf; 930 FILE_BASIC_INFO info_buf;
884 931
885 if (attrs == NULL) 932 if (attrs == NULL)
@@ -918,13 +965,22 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
918 /* 965 /*
919 * If the file is already open for write, just use that fileid 966 * If the file is already open for write, just use that fileid
920 */ 967 */
921 open_file = find_writable_file(cifsInode); 968 open_file = find_writable_file(cifsInode, true);
922 if (open_file) { 969 if (open_file) {
923 netfid = open_file->netfid; 970 netfid = open_file->netfid;
924 netpid = open_file->pid; 971 netpid = open_file->pid;
972 pTcon = tlink_tcon(open_file->tlink);
925 goto set_via_filehandle; 973 goto set_via_filehandle;
926 } 974 }
927 975
976 tlink = cifs_sb_tlink(cifs_sb);
977 if (IS_ERR(tlink)) {
978 rc = PTR_ERR(tlink);
979 tlink = NULL;
980 goto out;
981 }
982 pTcon = tlink_tcon(tlink);
983
928 /* 984 /*
929 * NT4 apparently returns success on this call, but it doesn't 985 * NT4 apparently returns success on this call, but it doesn't
930 * really work. 986 * really work.
@@ -968,6 +1024,8 @@ set_via_filehandle:
968 else 1024 else
969 cifsFileInfo_put(open_file); 1025 cifsFileInfo_put(open_file);
970out: 1026out:
1027 if (tlink != NULL)
1028 cifs_put_tlink(tlink);
971 return rc; 1029 return rc;
972} 1030}
973 1031
@@ -985,10 +1043,16 @@ cifs_rename_pending_delete(char *full_path, struct dentry *dentry, int xid)
985 struct inode *inode = dentry->d_inode; 1043 struct inode *inode = dentry->d_inode;
986 struct cifsInodeInfo *cifsInode = CIFS_I(inode); 1044 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
987 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 1045 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
988 struct cifsTconInfo *tcon = cifs_sb->tcon; 1046 struct tcon_link *tlink;
1047 struct cifsTconInfo *tcon;
989 __u32 dosattr, origattr; 1048 __u32 dosattr, origattr;
990 FILE_BASIC_INFO *info_buf = NULL; 1049 FILE_BASIC_INFO *info_buf = NULL;
991 1050
1051 tlink = cifs_sb_tlink(cifs_sb);
1052 if (IS_ERR(tlink))
1053 return PTR_ERR(tlink);
1054 tcon = tlink_tcon(tlink);
1055
992 rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN, 1056 rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN,
993 DELETE|FILE_WRITE_ATTRIBUTES, CREATE_NOT_DIR, 1057 DELETE|FILE_WRITE_ATTRIBUTES, CREATE_NOT_DIR,
994 &netfid, &oplock, NULL, cifs_sb->local_nls, 1058 &netfid, &oplock, NULL, cifs_sb->local_nls,
@@ -1057,6 +1121,7 @@ out_close:
1057 CIFSSMBClose(xid, tcon, netfid); 1121 CIFSSMBClose(xid, tcon, netfid);
1058out: 1122out:
1059 kfree(info_buf); 1123 kfree(info_buf);
1124 cifs_put_tlink(tlink);
1060 return rc; 1125 return rc;
1061 1126
1062 /* 1127 /*
@@ -1096,12 +1161,18 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
1096 struct cifsInodeInfo *cifs_inode; 1161 struct cifsInodeInfo *cifs_inode;
1097 struct super_block *sb = dir->i_sb; 1162 struct super_block *sb = dir->i_sb;
1098 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 1163 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1099 struct cifsTconInfo *tcon = cifs_sb->tcon; 1164 struct tcon_link *tlink;
1165 struct cifsTconInfo *tcon;
1100 struct iattr *attrs = NULL; 1166 struct iattr *attrs = NULL;
1101 __u32 dosattr = 0, origattr = 0; 1167 __u32 dosattr = 0, origattr = 0;
1102 1168
1103 cFYI(1, "cifs_unlink, dir=0x%p, dentry=0x%p", dir, dentry); 1169 cFYI(1, "cifs_unlink, dir=0x%p, dentry=0x%p", dir, dentry);
1104 1170
1171 tlink = cifs_sb_tlink(cifs_sb);
1172 if (IS_ERR(tlink))
1173 return PTR_ERR(tlink);
1174 tcon = tlink_tcon(tlink);
1175
1105 xid = GetXid(); 1176 xid = GetXid();
1106 1177
1107 /* Unlink can be called from rename so we can not take the 1178 /* Unlink can be called from rename so we can not take the
@@ -1109,8 +1180,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
1109 full_path = build_path_from_dentry(dentry); 1180 full_path = build_path_from_dentry(dentry);
1110 if (full_path == NULL) { 1181 if (full_path == NULL) {
1111 rc = -ENOMEM; 1182 rc = -ENOMEM;
1112 FreeXid(xid); 1183 goto unlink_out;
1113 return rc;
1114 } 1184 }
1115 1185
1116 if ((tcon->ses->capabilities & CAP_UNIX) && 1186 if ((tcon->ses->capabilities & CAP_UNIX) &&
@@ -1176,10 +1246,11 @@ out_reval:
1176 dir->i_ctime = dir->i_mtime = current_fs_time(sb); 1246 dir->i_ctime = dir->i_mtime = current_fs_time(sb);
1177 cifs_inode = CIFS_I(dir); 1247 cifs_inode = CIFS_I(dir);
1178 CIFS_I(dir)->time = 0; /* force revalidate of dir as well */ 1248 CIFS_I(dir)->time = 0; /* force revalidate of dir as well */
1179 1249unlink_out:
1180 kfree(full_path); 1250 kfree(full_path);
1181 kfree(attrs); 1251 kfree(attrs);
1182 FreeXid(xid); 1252 FreeXid(xid);
1253 cifs_put_tlink(tlink);
1183 return rc; 1254 return rc;
1184} 1255}
1185 1256
@@ -1188,6 +1259,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
1188 int rc = 0, tmprc; 1259 int rc = 0, tmprc;
1189 int xid; 1260 int xid;
1190 struct cifs_sb_info *cifs_sb; 1261 struct cifs_sb_info *cifs_sb;
1262 struct tcon_link *tlink;
1191 struct cifsTconInfo *pTcon; 1263 struct cifsTconInfo *pTcon;
1192 char *full_path = NULL; 1264 char *full_path = NULL;
1193 struct inode *newinode = NULL; 1265 struct inode *newinode = NULL;
@@ -1195,16 +1267,18 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
1195 1267
1196 cFYI(1, "In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode); 1268 cFYI(1, "In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode);
1197 1269
1198 xid = GetXid();
1199
1200 cifs_sb = CIFS_SB(inode->i_sb); 1270 cifs_sb = CIFS_SB(inode->i_sb);
1201 pTcon = cifs_sb->tcon; 1271 tlink = cifs_sb_tlink(cifs_sb);
1272 if (IS_ERR(tlink))
1273 return PTR_ERR(tlink);
1274 pTcon = tlink_tcon(tlink);
1275
1276 xid = GetXid();
1202 1277
1203 full_path = build_path_from_dentry(direntry); 1278 full_path = build_path_from_dentry(direntry);
1204 if (full_path == NULL) { 1279 if (full_path == NULL) {
1205 rc = -ENOMEM; 1280 rc = -ENOMEM;
1206 FreeXid(xid); 1281 goto mkdir_out;
1207 return rc;
1208 } 1282 }
1209 1283
1210 if ((pTcon->ses->capabilities & CAP_UNIX) && 1284 if ((pTcon->ses->capabilities & CAP_UNIX) &&
@@ -1362,6 +1436,7 @@ mkdir_get_info:
1362mkdir_out: 1436mkdir_out:
1363 kfree(full_path); 1437 kfree(full_path);
1364 FreeXid(xid); 1438 FreeXid(xid);
1439 cifs_put_tlink(tlink);
1365 return rc; 1440 return rc;
1366} 1441}
1367 1442
@@ -1370,6 +1445,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
1370 int rc = 0; 1445 int rc = 0;
1371 int xid; 1446 int xid;
1372 struct cifs_sb_info *cifs_sb; 1447 struct cifs_sb_info *cifs_sb;
1448 struct tcon_link *tlink;
1373 struct cifsTconInfo *pTcon; 1449 struct cifsTconInfo *pTcon;
1374 char *full_path = NULL; 1450 char *full_path = NULL;
1375 struct cifsInodeInfo *cifsInode; 1451 struct cifsInodeInfo *cifsInode;
@@ -1378,18 +1454,23 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
1378 1454
1379 xid = GetXid(); 1455 xid = GetXid();
1380 1456
1381 cifs_sb = CIFS_SB(inode->i_sb);
1382 pTcon = cifs_sb->tcon;
1383
1384 full_path = build_path_from_dentry(direntry); 1457 full_path = build_path_from_dentry(direntry);
1385 if (full_path == NULL) { 1458 if (full_path == NULL) {
1386 rc = -ENOMEM; 1459 rc = -ENOMEM;
1387 FreeXid(xid); 1460 goto rmdir_exit;
1388 return rc;
1389 } 1461 }
1390 1462
1463 cifs_sb = CIFS_SB(inode->i_sb);
1464 tlink = cifs_sb_tlink(cifs_sb);
1465 if (IS_ERR(tlink)) {
1466 rc = PTR_ERR(tlink);
1467 goto rmdir_exit;
1468 }
1469 pTcon = tlink_tcon(tlink);
1470
1391 rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls, 1471 rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls,
1392 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 1472 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1473 cifs_put_tlink(tlink);
1393 1474
1394 if (!rc) { 1475 if (!rc) {
1395 drop_nlink(inode); 1476 drop_nlink(inode);
@@ -1410,6 +1491,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
1410 direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime = 1491 direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime =
1411 current_fs_time(inode->i_sb); 1492 current_fs_time(inode->i_sb);
1412 1493
1494rmdir_exit:
1413 kfree(full_path); 1495 kfree(full_path);
1414 FreeXid(xid); 1496 FreeXid(xid);
1415 return rc; 1497 return rc;
@@ -1420,10 +1502,16 @@ cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath,
1420 struct dentry *to_dentry, const char *toPath) 1502 struct dentry *to_dentry, const char *toPath)
1421{ 1503{
1422 struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb); 1504 struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb);
1423 struct cifsTconInfo *pTcon = cifs_sb->tcon; 1505 struct tcon_link *tlink;
1506 struct cifsTconInfo *pTcon;
1424 __u16 srcfid; 1507 __u16 srcfid;
1425 int oplock, rc; 1508 int oplock, rc;
1426 1509
1510 tlink = cifs_sb_tlink(cifs_sb);
1511 if (IS_ERR(tlink))
1512 return PTR_ERR(tlink);
1513 pTcon = tlink_tcon(tlink);
1514
1427 /* try path-based rename first */ 1515 /* try path-based rename first */
1428 rc = CIFSSMBRename(xid, pTcon, fromPath, toPath, cifs_sb->local_nls, 1516 rc = CIFSSMBRename(xid, pTcon, fromPath, toPath, cifs_sb->local_nls,
1429 cifs_sb->mnt_cifs_flags & 1517 cifs_sb->mnt_cifs_flags &
@@ -1435,11 +1523,11 @@ cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath,
1435 * rename by filehandle to various Windows servers. 1523 * rename by filehandle to various Windows servers.
1436 */ 1524 */
1437 if (rc == 0 || rc != -ETXTBSY) 1525 if (rc == 0 || rc != -ETXTBSY)
1438 return rc; 1526 goto do_rename_exit;
1439 1527
1440 /* open-file renames don't work across directories */ 1528 /* open-file renames don't work across directories */
1441 if (to_dentry->d_parent != from_dentry->d_parent) 1529 if (to_dentry->d_parent != from_dentry->d_parent)
1442 return rc; 1530 goto do_rename_exit;
1443 1531
1444 /* open the file to be renamed -- we need DELETE perms */ 1532 /* open the file to be renamed -- we need DELETE perms */
1445 rc = CIFSSMBOpen(xid, pTcon, fromPath, FILE_OPEN, DELETE, 1533 rc = CIFSSMBOpen(xid, pTcon, fromPath, FILE_OPEN, DELETE,
@@ -1455,7 +1543,8 @@ cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath,
1455 1543
1456 CIFSSMBClose(xid, pTcon, srcfid); 1544 CIFSSMBClose(xid, pTcon, srcfid);
1457 } 1545 }
1458 1546do_rename_exit:
1547 cifs_put_tlink(tlink);
1459 return rc; 1548 return rc;
1460} 1549}
1461 1550
@@ -1465,13 +1554,17 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
1465 char *fromName = NULL; 1554 char *fromName = NULL;
1466 char *toName = NULL; 1555 char *toName = NULL;
1467 struct cifs_sb_info *cifs_sb; 1556 struct cifs_sb_info *cifs_sb;
1557 struct tcon_link *tlink;
1468 struct cifsTconInfo *tcon; 1558 struct cifsTconInfo *tcon;
1469 FILE_UNIX_BASIC_INFO *info_buf_source = NULL; 1559 FILE_UNIX_BASIC_INFO *info_buf_source = NULL;
1470 FILE_UNIX_BASIC_INFO *info_buf_target; 1560 FILE_UNIX_BASIC_INFO *info_buf_target;
1471 int xid, rc, tmprc; 1561 int xid, rc, tmprc;
1472 1562
1473 cifs_sb = CIFS_SB(source_dir->i_sb); 1563 cifs_sb = CIFS_SB(source_dir->i_sb);
1474 tcon = cifs_sb->tcon; 1564 tlink = cifs_sb_tlink(cifs_sb);
1565 if (IS_ERR(tlink))
1566 return PTR_ERR(tlink);
1567 tcon = tlink_tcon(tlink);
1475 1568
1476 xid = GetXid(); 1569 xid = GetXid();
1477 1570
@@ -1547,6 +1640,7 @@ cifs_rename_exit:
1547 kfree(fromName); 1640 kfree(fromName);
1548 kfree(toName); 1641 kfree(toName);
1549 FreeXid(xid); 1642 FreeXid(xid);
1643 cifs_put_tlink(tlink);
1550 return rc; 1644 return rc;
1551} 1645}
1552 1646
@@ -1599,11 +1693,12 @@ int cifs_revalidate_file(struct file *filp)
1599{ 1693{
1600 int rc = 0; 1694 int rc = 0;
1601 struct inode *inode = filp->f_path.dentry->d_inode; 1695 struct inode *inode = filp->f_path.dentry->d_inode;
1696 struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data;
1602 1697
1603 if (!cifs_inode_needs_reval(inode)) 1698 if (!cifs_inode_needs_reval(inode))
1604 goto check_inval; 1699 goto check_inval;
1605 1700
1606 if (CIFS_SB(inode->i_sb)->tcon->unix_ext) 1701 if (tlink_tcon(cfile->tlink)->unix_ext)
1607 rc = cifs_get_file_info_unix(filp); 1702 rc = cifs_get_file_info_unix(filp);
1608 else 1703 else
1609 rc = cifs_get_file_info(filp); 1704 rc = cifs_get_file_info(filp);
@@ -1644,7 +1739,7 @@ int cifs_revalidate_dentry(struct dentry *dentry)
1644 "jiffies %ld", full_path, inode, inode->i_count.counter, 1739 "jiffies %ld", full_path, inode, inode->i_count.counter,
1645 dentry, dentry->d_time, jiffies); 1740 dentry, dentry->d_time, jiffies);
1646 1741
1647 if (CIFS_SB(sb)->tcon->unix_ext) 1742 if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext)
1648 rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid); 1743 rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
1649 else 1744 else
1650 rc = cifs_get_inode_info(&inode, full_path, NULL, sb, 1745 rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
@@ -1662,11 +1757,21 @@ check_inval:
1662int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry, 1757int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
1663 struct kstat *stat) 1758 struct kstat *stat)
1664{ 1759{
1760 struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);
1761 struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
1665 int err = cifs_revalidate_dentry(dentry); 1762 int err = cifs_revalidate_dentry(dentry);
1763
1666 if (!err) { 1764 if (!err) {
1667 generic_fillattr(dentry->d_inode, stat); 1765 generic_fillattr(dentry->d_inode, stat);
1668 stat->blksize = CIFS_MAX_MSGSIZE; 1766 stat->blksize = CIFS_MAX_MSGSIZE;
1669 stat->ino = CIFS_I(dentry->d_inode)->uniqueid; 1767 stat->ino = CIFS_I(dentry->d_inode)->uniqueid;
1768 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) &&
1769 !tcon->unix_ext) {
1770 if (!cifs_sb->mnt_uid)
1771 stat->uid = current_fsuid();
1772 if (!cifs_sb->mnt_uid)
1773 stat->gid = current_fsgid();
1774 }
1670 } 1775 }
1671 return err; 1776 return err;
1672} 1777}
@@ -1708,7 +1813,8 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1708 struct cifsFileInfo *open_file; 1813 struct cifsFileInfo *open_file;
1709 struct cifsInodeInfo *cifsInode = CIFS_I(inode); 1814 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1710 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 1815 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1711 struct cifsTconInfo *pTcon = cifs_sb->tcon; 1816 struct tcon_link *tlink = NULL;
1817 struct cifsTconInfo *pTcon = NULL;
1712 1818
1713 /* 1819 /*
1714 * To avoid spurious oplock breaks from server, in the case of 1820 * To avoid spurious oplock breaks from server, in the case of
@@ -1719,10 +1825,11 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1719 * writebehind data than the SMB timeout for the SetPathInfo 1825 * writebehind data than the SMB timeout for the SetPathInfo
1720 * request would allow 1826 * request would allow
1721 */ 1827 */
1722 open_file = find_writable_file(cifsInode); 1828 open_file = find_writable_file(cifsInode, true);
1723 if (open_file) { 1829 if (open_file) {
1724 __u16 nfid = open_file->netfid; 1830 __u16 nfid = open_file->netfid;
1725 __u32 npid = open_file->pid; 1831 __u32 npid = open_file->pid;
1832 pTcon = tlink_tcon(open_file->tlink);
1726 rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid, 1833 rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid,
1727 npid, false); 1834 npid, false);
1728 cifsFileInfo_put(open_file); 1835 cifsFileInfo_put(open_file);
@@ -1737,6 +1844,13 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1737 rc = -EINVAL; 1844 rc = -EINVAL;
1738 1845
1739 if (rc != 0) { 1846 if (rc != 0) {
1847 if (pTcon == NULL) {
1848 tlink = cifs_sb_tlink(cifs_sb);
1849 if (IS_ERR(tlink))
1850 return PTR_ERR(tlink);
1851 pTcon = tlink_tcon(tlink);
1852 }
1853
1740 /* Set file size by pathname rather than by handle 1854 /* Set file size by pathname rather than by handle
1741 either because no valid, writeable file handle for 1855 either because no valid, writeable file handle for
1742 it was found or because there was an error setting 1856 it was found or because there was an error setting
@@ -1766,6 +1880,8 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1766 CIFSSMBClose(xid, pTcon, netfid); 1880 CIFSSMBClose(xid, pTcon, netfid);
1767 } 1881 }
1768 } 1882 }
1883 if (tlink)
1884 cifs_put_tlink(tlink);
1769 } 1885 }
1770 1886
1771 if (rc == 0) { 1887 if (rc == 0) {
@@ -1786,7 +1902,8 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
1786 struct inode *inode = direntry->d_inode; 1902 struct inode *inode = direntry->d_inode;
1787 struct cifsInodeInfo *cifsInode = CIFS_I(inode); 1903 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1788 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 1904 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1789 struct cifsTconInfo *pTcon = cifs_sb->tcon; 1905 struct tcon_link *tlink;
1906 struct cifsTconInfo *pTcon;
1790 struct cifs_unix_set_info_args *args = NULL; 1907 struct cifs_unix_set_info_args *args = NULL;
1791 struct cifsFileInfo *open_file; 1908 struct cifsFileInfo *open_file;
1792 1909
@@ -1873,17 +1990,25 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
1873 args->ctime = NO_CHANGE_64; 1990 args->ctime = NO_CHANGE_64;
1874 1991
1875 args->device = 0; 1992 args->device = 0;
1876 open_file = find_writable_file(cifsInode); 1993 open_file = find_writable_file(cifsInode, true);
1877 if (open_file) { 1994 if (open_file) {
1878 u16 nfid = open_file->netfid; 1995 u16 nfid = open_file->netfid;
1879 u32 npid = open_file->pid; 1996 u32 npid = open_file->pid;
1997 pTcon = tlink_tcon(open_file->tlink);
1880 rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid); 1998 rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid);
1881 cifsFileInfo_put(open_file); 1999 cifsFileInfo_put(open_file);
1882 } else { 2000 } else {
2001 tlink = cifs_sb_tlink(cifs_sb);
2002 if (IS_ERR(tlink)) {
2003 rc = PTR_ERR(tlink);
2004 goto out;
2005 }
2006 pTcon = tlink_tcon(tlink);
1883 rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args, 2007 rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args,
1884 cifs_sb->local_nls, 2008 cifs_sb->local_nls,
1885 cifs_sb->mnt_cifs_flags & 2009 cifs_sb->mnt_cifs_flags &
1886 CIFS_MOUNT_MAP_SPECIAL_CHR); 2010 CIFS_MOUNT_MAP_SPECIAL_CHR);
2011 cifs_put_tlink(tlink);
1887 } 2012 }
1888 2013
1889 if (rc) 2014 if (rc)
@@ -2064,7 +2189,7 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs)
2064{ 2189{
2065 struct inode *inode = direntry->d_inode; 2190 struct inode *inode = direntry->d_inode;
2066 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 2191 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
2067 struct cifsTconInfo *pTcon = cifs_sb->tcon; 2192 struct cifsTconInfo *pTcon = cifs_sb_master_tcon(cifs_sb);
2068 2193
2069 if (pTcon->unix_ext) 2194 if (pTcon->unix_ext)
2070 return cifs_setattr_unix(direntry, attrs); 2195 return cifs_setattr_unix(direntry, attrs);
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c
index 9d38a71c8e14..077bf756f342 100644
--- a/fs/cifs/ioctl.c
+++ b/fs/cifs/ioctl.c
@@ -37,11 +37,11 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
37 int xid; 37 int xid;
38 struct cifs_sb_info *cifs_sb; 38 struct cifs_sb_info *cifs_sb;
39#ifdef CONFIG_CIFS_POSIX 39#ifdef CONFIG_CIFS_POSIX
40 struct cifsFileInfo *pSMBFile = filep->private_data;
41 struct cifsTconInfo *tcon = tlink_tcon(pSMBFile->tlink);
40 __u64 ExtAttrBits = 0; 42 __u64 ExtAttrBits = 0;
41 __u64 ExtAttrMask = 0; 43 __u64 ExtAttrMask = 0;
42 __u64 caps; 44 __u64 caps = le64_to_cpu(tcon->fsUnixInfo.Capability);
43 struct cifsTconInfo *tcon;
44 struct cifsFileInfo *pSMBFile = filep->private_data;
45#endif /* CONFIG_CIFS_POSIX */ 45#endif /* CONFIG_CIFS_POSIX */
46 46
47 xid = GetXid(); 47 xid = GetXid();
@@ -50,17 +50,6 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
50 50
51 cifs_sb = CIFS_SB(inode->i_sb); 51 cifs_sb = CIFS_SB(inode->i_sb);
52 52
53#ifdef CONFIG_CIFS_POSIX
54 tcon = cifs_sb->tcon;
55 if (tcon)
56 caps = le64_to_cpu(tcon->fsUnixInfo.Capability);
57 else {
58 rc = -EIO;
59 FreeXid(xid);
60 return -EIO;
61 }
62#endif /* CONFIG_CIFS_POSIX */
63
64 switch (command) { 53 switch (command) {
65 case CIFS_IOC_CHECKUMOUNT: 54 case CIFS_IOC_CHECKUMOUNT:
66 cFYI(1, "User unmount attempted"); 55 cFYI(1, "User unmount attempted");
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 473ca8033656..85cdbf831e7b 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -28,6 +28,296 @@
28#include "cifsproto.h" 28#include "cifsproto.h"
29#include "cifs_debug.h" 29#include "cifs_debug.h"
30#include "cifs_fs_sb.h" 30#include "cifs_fs_sb.h"
31#include "md5.h"
32
33#define CIFS_MF_SYMLINK_LEN_OFFSET (4+1)
34#define CIFS_MF_SYMLINK_MD5_OFFSET (CIFS_MF_SYMLINK_LEN_OFFSET+(4+1))
35#define CIFS_MF_SYMLINK_LINK_OFFSET (CIFS_MF_SYMLINK_MD5_OFFSET+(32+1))
36#define CIFS_MF_SYMLINK_LINK_MAXLEN (1024)
37#define CIFS_MF_SYMLINK_FILE_SIZE \
38 (CIFS_MF_SYMLINK_LINK_OFFSET + CIFS_MF_SYMLINK_LINK_MAXLEN)
39
40#define CIFS_MF_SYMLINK_LEN_FORMAT "XSym\n%04u\n"
41#define CIFS_MF_SYMLINK_MD5_FORMAT \
42 "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n"
43#define CIFS_MF_SYMLINK_MD5_ARGS(md5_hash) \
44 md5_hash[0], md5_hash[1], md5_hash[2], md5_hash[3], \
45 md5_hash[4], md5_hash[5], md5_hash[6], md5_hash[7], \
46 md5_hash[8], md5_hash[9], md5_hash[10], md5_hash[11],\
47 md5_hash[12], md5_hash[13], md5_hash[14], md5_hash[15]
48
49static int
50CIFSParseMFSymlink(const u8 *buf,
51 unsigned int buf_len,
52 unsigned int *_link_len,
53 char **_link_str)
54{
55 int rc;
56 unsigned int link_len;
57 const char *md5_str1;
58 const char *link_str;
59 struct MD5Context md5_ctx;
60 u8 md5_hash[16];
61 char md5_str2[34];
62
63 if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE)
64 return -EINVAL;
65
66 md5_str1 = (const char *)&buf[CIFS_MF_SYMLINK_MD5_OFFSET];
67 link_str = (const char *)&buf[CIFS_MF_SYMLINK_LINK_OFFSET];
68
69 rc = sscanf(buf, CIFS_MF_SYMLINK_LEN_FORMAT, &link_len);
70 if (rc != 1)
71 return -EINVAL;
72
73 cifs_MD5_init(&md5_ctx);
74 cifs_MD5_update(&md5_ctx, (const u8 *)link_str, link_len);
75 cifs_MD5_final(md5_hash, &md5_ctx);
76
77 snprintf(md5_str2, sizeof(md5_str2),
78 CIFS_MF_SYMLINK_MD5_FORMAT,
79 CIFS_MF_SYMLINK_MD5_ARGS(md5_hash));
80
81 if (strncmp(md5_str1, md5_str2, 17) != 0)
82 return -EINVAL;
83
84 if (_link_str) {
85 *_link_str = kstrndup(link_str, link_len, GFP_KERNEL);
86 if (!*_link_str)
87 return -ENOMEM;
88 }
89
90 *_link_len = link_len;
91 return 0;
92}
93
94static int
95CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str)
96{
97 unsigned int link_len;
98 unsigned int ofs;
99 struct MD5Context md5_ctx;
100 u8 md5_hash[16];
101
102 if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE)
103 return -EINVAL;
104
105 link_len = strlen(link_str);
106
107 if (link_len > CIFS_MF_SYMLINK_LINK_MAXLEN)
108 return -ENAMETOOLONG;
109
110 cifs_MD5_init(&md5_ctx);
111 cifs_MD5_update(&md5_ctx, (const u8 *)link_str, link_len);
112 cifs_MD5_final(md5_hash, &md5_ctx);
113
114 snprintf(buf, buf_len,
115 CIFS_MF_SYMLINK_LEN_FORMAT CIFS_MF_SYMLINK_MD5_FORMAT,
116 link_len,
117 CIFS_MF_SYMLINK_MD5_ARGS(md5_hash));
118
119 ofs = CIFS_MF_SYMLINK_LINK_OFFSET;
120 memcpy(buf + ofs, link_str, link_len);
121
122 ofs += link_len;
123 if (ofs < CIFS_MF_SYMLINK_FILE_SIZE) {
124 buf[ofs] = '\n';
125 ofs++;
126 }
127
128 while (ofs < CIFS_MF_SYMLINK_FILE_SIZE) {
129 buf[ofs] = ' ';
130 ofs++;
131 }
132
133 return 0;
134}
135
136static int
137CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
138 const char *fromName, const char *toName,
139 const struct nls_table *nls_codepage, int remap)
140{
141 int rc;
142 int oplock = 0;
143 __u16 netfid = 0;
144 u8 *buf;
145 unsigned int bytes_written = 0;
146
147 buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
148 if (!buf)
149 return -ENOMEM;
150
151 rc = CIFSFormatMFSymlink(buf, CIFS_MF_SYMLINK_FILE_SIZE, toName);
152 if (rc != 0) {
153 kfree(buf);
154 return rc;
155 }
156
157 rc = CIFSSMBOpen(xid, tcon, fromName, FILE_CREATE, GENERIC_WRITE,
158 CREATE_NOT_DIR, &netfid, &oplock, NULL,
159 nls_codepage, remap);
160 if (rc != 0) {
161 kfree(buf);
162 return rc;
163 }
164
165 rc = CIFSSMBWrite(xid, tcon, netfid,
166 CIFS_MF_SYMLINK_FILE_SIZE /* length */,
167 0 /* offset */,
168 &bytes_written, buf, NULL, 0);
169 CIFSSMBClose(xid, tcon, netfid);
170 kfree(buf);
171 if (rc != 0)
172 return rc;
173
174 if (bytes_written != CIFS_MF_SYMLINK_FILE_SIZE)
175 return -EIO;
176
177 return 0;
178}
179
180static int
181CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
182 const unsigned char *searchName, char **symlinkinfo,
183 const struct nls_table *nls_codepage, int remap)
184{
185 int rc;
186 int oplock = 0;
187 __u16 netfid = 0;
188 u8 *buf;
189 char *pbuf;
190 unsigned int bytes_read = 0;
191 int buf_type = CIFS_NO_BUFFER;
192 unsigned int link_len = 0;
193 FILE_ALL_INFO file_info;
194
195 rc = CIFSSMBOpen(xid, tcon, searchName, FILE_OPEN, GENERIC_READ,
196 CREATE_NOT_DIR, &netfid, &oplock, &file_info,
197 nls_codepage, remap);
198 if (rc != 0)
199 return rc;
200
201 if (file_info.EndOfFile != CIFS_MF_SYMLINK_FILE_SIZE) {
202 CIFSSMBClose(xid, tcon, netfid);
203 /* it's not a symlink */
204 return -EINVAL;
205 }
206
207 buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
208 if (!buf)
209 return -ENOMEM;
210 pbuf = buf;
211
212 rc = CIFSSMBRead(xid, tcon, netfid,
213 CIFS_MF_SYMLINK_FILE_SIZE /* length */,
214 0 /* offset */,
215 &bytes_read, &pbuf, &buf_type);
216 CIFSSMBClose(xid, tcon, netfid);
217 if (rc != 0) {
218 kfree(buf);
219 return rc;
220 }
221
222 rc = CIFSParseMFSymlink(buf, bytes_read, &link_len, symlinkinfo);
223 kfree(buf);
224 if (rc != 0)
225 return rc;
226
227 return 0;
228}
229
230bool
231CIFSCouldBeMFSymlink(const struct cifs_fattr *fattr)
232{
233 if (!(fattr->cf_mode & S_IFREG))
234 /* it's not a symlink */
235 return false;
236
237 if (fattr->cf_eof != CIFS_MF_SYMLINK_FILE_SIZE)
238 /* it's not a symlink */
239 return false;
240
241 return true;
242}
243
244int
245CIFSCheckMFSymlink(struct cifs_fattr *fattr,
246 const unsigned char *path,
247 struct cifs_sb_info *cifs_sb, int xid)
248{
249 int rc;
250 int oplock = 0;
251 __u16 netfid = 0;
252 struct tcon_link *tlink;
253 struct cifsTconInfo *pTcon;
254 u8 *buf;
255 char *pbuf;
256 unsigned int bytes_read = 0;
257 int buf_type = CIFS_NO_BUFFER;
258 unsigned int link_len = 0;
259 FILE_ALL_INFO file_info;
260
261 if (!CIFSCouldBeMFSymlink(fattr))
262 /* it's not a symlink */
263 return 0;
264
265 tlink = cifs_sb_tlink(cifs_sb);
266 if (IS_ERR(tlink))
267 return PTR_ERR(tlink);
268 pTcon = tlink_tcon(tlink);
269
270 rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ,
271 CREATE_NOT_DIR, &netfid, &oplock, &file_info,
272 cifs_sb->local_nls,
273 cifs_sb->mnt_cifs_flags &
274 CIFS_MOUNT_MAP_SPECIAL_CHR);
275 if (rc != 0)
276 goto out;
277
278 if (file_info.EndOfFile != CIFS_MF_SYMLINK_FILE_SIZE) {
279 CIFSSMBClose(xid, pTcon, netfid);
280 /* it's not a symlink */
281 goto out;
282 }
283
284 buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
285 if (!buf) {
286 rc = -ENOMEM;
287 goto out;
288 }
289 pbuf = buf;
290
291 rc = CIFSSMBRead(xid, pTcon, netfid,
292 CIFS_MF_SYMLINK_FILE_SIZE /* length */,
293 0 /* offset */,
294 &bytes_read, &pbuf, &buf_type);
295 CIFSSMBClose(xid, pTcon, netfid);
296 if (rc != 0) {
297 kfree(buf);
298 goto out;
299 }
300
301 rc = CIFSParseMFSymlink(buf, bytes_read, &link_len, NULL);
302 kfree(buf);
303 if (rc == -EINVAL) {
304 /* it's not a symlink */
305 rc = 0;
306 goto out;
307 }
308
309 if (rc != 0)
310 goto out;
311
312 /* it is a symlink */
313 fattr->cf_eof = link_len;
314 fattr->cf_mode &= ~S_IFMT;
315 fattr->cf_mode |= S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO;
316 fattr->cf_dtype = DT_LNK;
317out:
318 cifs_put_tlink(tlink);
319 return rc;
320}
31 321
32int 322int
33cifs_hardlink(struct dentry *old_file, struct inode *inode, 323cifs_hardlink(struct dentry *old_file, struct inode *inode,
@@ -37,17 +327,17 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
37 int xid; 327 int xid;
38 char *fromName = NULL; 328 char *fromName = NULL;
39 char *toName = NULL; 329 char *toName = NULL;
40 struct cifs_sb_info *cifs_sb_target; 330 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
331 struct tcon_link *tlink;
41 struct cifsTconInfo *pTcon; 332 struct cifsTconInfo *pTcon;
42 struct cifsInodeInfo *cifsInode; 333 struct cifsInodeInfo *cifsInode;
43 334
44 xid = GetXid(); 335 tlink = cifs_sb_tlink(cifs_sb);
45 336 if (IS_ERR(tlink))
46 cifs_sb_target = CIFS_SB(inode->i_sb); 337 return PTR_ERR(tlink);
47 pTcon = cifs_sb_target->tcon; 338 pTcon = tlink_tcon(tlink);
48 339
49/* No need to check for cross device links since server will do that 340 xid = GetXid();
50 BB note DFS case in future though (when we may have to check) */
51 341
52 fromName = build_path_from_dentry(old_file); 342 fromName = build_path_from_dentry(old_file);
53 toName = build_path_from_dentry(direntry); 343 toName = build_path_from_dentry(direntry);
@@ -56,16 +346,15 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
56 goto cifs_hl_exit; 346 goto cifs_hl_exit;
57 } 347 }
58 348
59/* if (cifs_sb_target->tcon->ses->capabilities & CAP_UNIX)*/
60 if (pTcon->unix_ext) 349 if (pTcon->unix_ext)
61 rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName, 350 rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName,
62 cifs_sb_target->local_nls, 351 cifs_sb->local_nls,
63 cifs_sb_target->mnt_cifs_flags & 352 cifs_sb->mnt_cifs_flags &
64 CIFS_MOUNT_MAP_SPECIAL_CHR); 353 CIFS_MOUNT_MAP_SPECIAL_CHR);
65 else { 354 else {
66 rc = CIFSCreateHardLink(xid, pTcon, fromName, toName, 355 rc = CIFSCreateHardLink(xid, pTcon, fromName, toName,
67 cifs_sb_target->local_nls, 356 cifs_sb->local_nls,
68 cifs_sb_target->mnt_cifs_flags & 357 cifs_sb->mnt_cifs_flags &
69 CIFS_MOUNT_MAP_SPECIAL_CHR); 358 CIFS_MOUNT_MAP_SPECIAL_CHR);
70 if ((rc == -EIO) || (rc == -EINVAL)) 359 if ((rc == -EIO) || (rc == -EINVAL))
71 rc = -EOPNOTSUPP; 360 rc = -EOPNOTSUPP;
@@ -101,6 +390,7 @@ cifs_hl_exit:
101 kfree(fromName); 390 kfree(fromName);
102 kfree(toName); 391 kfree(toName);
103 FreeXid(xid); 392 FreeXid(xid);
393 cifs_put_tlink(tlink);
104 return rc; 394 return rc;
105} 395}
106 396
@@ -113,10 +403,19 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
113 char *full_path = NULL; 403 char *full_path = NULL;
114 char *target_path = NULL; 404 char *target_path = NULL;
115 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 405 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
116 struct cifsTconInfo *tcon = cifs_sb->tcon; 406 struct tcon_link *tlink = NULL;
407 struct cifsTconInfo *tcon;
117 408
118 xid = GetXid(); 409 xid = GetXid();
119 410
411 tlink = cifs_sb_tlink(cifs_sb);
412 if (IS_ERR(tlink)) {
413 rc = PTR_ERR(tlink);
414 tlink = NULL;
415 goto out;
416 }
417 tcon = tlink_tcon(tlink);
418
120 /* 419 /*
121 * For now, we just handle symlinks with unix extensions enabled. 420 * For now, we just handle symlinks with unix extensions enabled.
122 * Eventually we should handle NTFS reparse points, and MacOS 421 * Eventually we should handle NTFS reparse points, and MacOS
@@ -130,7 +429,8 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
130 * but there doesn't seem to be any harm in allowing the client to 429 * but there doesn't seem to be any harm in allowing the client to
131 * read them. 430 * read them.
132 */ 431 */
133 if (!(tcon->ses->capabilities & CAP_UNIX)) { 432 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
433 && !(tcon->ses->capabilities & CAP_UNIX)) {
134 rc = -EACCES; 434 rc = -EACCES;
135 goto out; 435 goto out;
136 } 436 }
@@ -141,8 +441,21 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
141 441
142 cFYI(1, "Full path: %s inode = 0x%p", full_path, inode); 442 cFYI(1, "Full path: %s inode = 0x%p", full_path, inode);
143 443
144 rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path, 444 rc = -EACCES;
145 cifs_sb->local_nls); 445 /*
446 * First try Minshall+French Symlinks, if configured
447 * and fallback to UNIX Extensions Symlinks.
448 */
449 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
450 rc = CIFSQueryMFSymLink(xid, tcon, full_path, &target_path,
451 cifs_sb->local_nls,
452 cifs_sb->mnt_cifs_flags &
453 CIFS_MOUNT_MAP_SPECIAL_CHR);
454
455 if ((rc != 0) && (tcon->ses->capabilities & CAP_UNIX))
456 rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path,
457 cifs_sb->local_nls);
458
146 kfree(full_path); 459 kfree(full_path);
147out: 460out:
148 if (rc != 0) { 461 if (rc != 0) {
@@ -151,6 +464,8 @@ out:
151 } 464 }
152 465
153 FreeXid(xid); 466 FreeXid(xid);
467 if (tlink)
468 cifs_put_tlink(tlink);
154 nd_set_link(nd, target_path); 469 nd_set_link(nd, target_path);
155 return NULL; 470 return NULL;
156} 471}
@@ -160,29 +475,37 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
160{ 475{
161 int rc = -EOPNOTSUPP; 476 int rc = -EOPNOTSUPP;
162 int xid; 477 int xid;
163 struct cifs_sb_info *cifs_sb; 478 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
479 struct tcon_link *tlink;
164 struct cifsTconInfo *pTcon; 480 struct cifsTconInfo *pTcon;
165 char *full_path = NULL; 481 char *full_path = NULL;
166 struct inode *newinode = NULL; 482 struct inode *newinode = NULL;
167 483
168 xid = GetXid(); 484 xid = GetXid();
169 485
170 cifs_sb = CIFS_SB(inode->i_sb); 486 tlink = cifs_sb_tlink(cifs_sb);
171 pTcon = cifs_sb->tcon; 487 if (IS_ERR(tlink)) {
488 rc = PTR_ERR(tlink);
489 goto symlink_exit;
490 }
491 pTcon = tlink_tcon(tlink);
172 492
173 full_path = build_path_from_dentry(direntry); 493 full_path = build_path_from_dentry(direntry);
174
175 if (full_path == NULL) { 494 if (full_path == NULL) {
176 rc = -ENOMEM; 495 rc = -ENOMEM;
177 FreeXid(xid); 496 goto symlink_exit;
178 return rc;
179 } 497 }
180 498
181 cFYI(1, "Full path: %s", full_path); 499 cFYI(1, "Full path: %s", full_path);
182 cFYI(1, "symname is %s", symname); 500 cFYI(1, "symname is %s", symname);
183 501
184 /* BB what if DFS and this volume is on different share? BB */ 502 /* BB what if DFS and this volume is on different share? BB */
185 if (pTcon->unix_ext) 503 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
504 rc = CIFSCreateMFSymLink(xid, pTcon, full_path, symname,
505 cifs_sb->local_nls,
506 cifs_sb->mnt_cifs_flags &
507 CIFS_MOUNT_MAP_SPECIAL_CHR);
508 else if (pTcon->unix_ext)
186 rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname, 509 rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname,
187 cifs_sb->local_nls); 510 cifs_sb->local_nls);
188 /* else 511 /* else
@@ -208,8 +531,9 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
208 d_instantiate(direntry, newinode); 531 d_instantiate(direntry, newinode);
209 } 532 }
210 } 533 }
211 534symlink_exit:
212 kfree(full_path); 535 kfree(full_path);
536 cifs_put_tlink(tlink);
213 FreeXid(xid); 537 FreeXid(xid);
214 return rc; 538 return rc;
215} 539}
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 3ccadc1326d6..252f2768db84 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -729,6 +729,6 @@ cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb)
729 "properly. Hardlinks will not be recognized on this " 729 "properly. Hardlinks will not be recognized on this "
730 "mount. Consider mounting with the \"noserverino\" " 730 "mount. Consider mounting with the \"noserverino\" "
731 "option to silence this message.", 731 "option to silence this message.",
732 cifs_sb->tcon->treeName); 732 cifs_sb_master_tcon(cifs_sb)->treeName);
733 } 733 }
734} 734}
diff --git a/fs/cifs/ntlmssp.h b/fs/cifs/ntlmssp.h
index 49c9a4e75319..5d52e4a3b1ed 100644
--- a/fs/cifs/ntlmssp.h
+++ b/fs/cifs/ntlmssp.h
@@ -61,6 +61,21 @@
61#define NTLMSSP_NEGOTIATE_KEY_XCH 0x40000000 61#define NTLMSSP_NEGOTIATE_KEY_XCH 0x40000000
62#define NTLMSSP_NEGOTIATE_56 0x80000000 62#define NTLMSSP_NEGOTIATE_56 0x80000000
63 63
64/* Define AV Pair Field IDs */
65enum av_field_type {
66 NTLMSSP_AV_EOL = 0,
67 NTLMSSP_AV_NB_COMPUTER_NAME,
68 NTLMSSP_AV_NB_DOMAIN_NAME,
69 NTLMSSP_AV_DNS_COMPUTER_NAME,
70 NTLMSSP_AV_DNS_DOMAIN_NAME,
71 NTLMSSP_AV_DNS_TREE_NAME,
72 NTLMSSP_AV_FLAGS,
73 NTLMSSP_AV_TIMESTAMP,
74 NTLMSSP_AV_RESTRICTION,
75 NTLMSSP_AV_TARGET_NAME,
76 NTLMSSP_AV_CHANNEL_BINDINGS
77};
78
64/* Although typedefs are not commonly used for structure definitions */ 79/* Although typedefs are not commonly used for structure definitions */
65/* in the Linux kernel, in this particular case they are useful */ 80/* in the Linux kernel, in this particular case they are useful */
66/* to more closely match the standards document for NTLMSSP from */ 81/* to more closely match the standards document for NTLMSSP from */
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index d5e591fab475..1f0bd0f972d4 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -102,7 +102,7 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
102 return NULL; 102 return NULL;
103 } 103 }
104 104
105 if (CIFS_SB(sb)->tcon->nocase) 105 if (cifs_sb_master_tcon(CIFS_SB(sb))->nocase)
106 dentry->d_op = &cifs_ci_dentry_ops; 106 dentry->d_op = &cifs_ci_dentry_ops;
107 else 107 else
108 dentry->d_op = &cifs_dentry_ops; 108 dentry->d_op = &cifs_dentry_ops;
@@ -171,7 +171,7 @@ static void
171cifs_std_info_to_fattr(struct cifs_fattr *fattr, FIND_FILE_STANDARD_INFO *info, 171cifs_std_info_to_fattr(struct cifs_fattr *fattr, FIND_FILE_STANDARD_INFO *info,
172 struct cifs_sb_info *cifs_sb) 172 struct cifs_sb_info *cifs_sb)
173{ 173{
174 int offset = cifs_sb->tcon->ses->server->timeAdj; 174 int offset = cifs_sb_master_tcon(cifs_sb)->ses->server->timeAdj;
175 175
176 memset(fattr, 0, sizeof(*fattr)); 176 memset(fattr, 0, sizeof(*fattr));
177 fattr->cf_atime = cnvrtDosUnixTm(info->LastAccessDate, 177 fattr->cf_atime = cnvrtDosUnixTm(info->LastAccessDate,
@@ -199,7 +199,7 @@ int get_symlink_reparse_path(char *full_path, struct cifs_sb_info *cifs_sb,
199 int len; 199 int len;
200 int oplock = 0; 200 int oplock = 0;
201 int rc; 201 int rc;
202 struct cifsTconInfo *ptcon = cifs_sb->tcon; 202 struct cifsTconInfo *ptcon = cifs_sb_tcon(cifs_sb);
203 char *tmpbuffer; 203 char *tmpbuffer;
204 204
205 rc = CIFSSMBOpen(xid, ptcon, full_path, FILE_OPEN, GENERIC_READ, 205 rc = CIFSSMBOpen(xid, ptcon, full_path, FILE_OPEN, GENERIC_READ,
@@ -223,34 +223,35 @@ int get_symlink_reparse_path(char *full_path, struct cifs_sb_info *cifs_sb,
223static int initiate_cifs_search(const int xid, struct file *file) 223static int initiate_cifs_search(const int xid, struct file *file)
224{ 224{
225 int rc = 0; 225 int rc = 0;
226 char *full_path; 226 char *full_path = NULL;
227 struct cifsFileInfo *cifsFile; 227 struct cifsFileInfo *cifsFile;
228 struct cifs_sb_info *cifs_sb; 228 struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
229 struct tcon_link *tlink;
229 struct cifsTconInfo *pTcon; 230 struct cifsTconInfo *pTcon;
230 231
231 if (file->private_data == NULL) { 232 tlink = cifs_sb_tlink(cifs_sb);
233 if (IS_ERR(tlink))
234 return PTR_ERR(tlink);
235 pTcon = tlink_tcon(tlink);
236
237 if (file->private_data == NULL)
232 file->private_data = 238 file->private_data =
233 kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); 239 kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
240 if (file->private_data == NULL) {
241 rc = -ENOMEM;
242 goto error_exit;
234 } 243 }
235 244
236 if (file->private_data == NULL)
237 return -ENOMEM;
238 cifsFile = file->private_data; 245 cifsFile = file->private_data;
239 cifsFile->invalidHandle = true; 246 cifsFile->invalidHandle = true;
240 cifsFile->srch_inf.endOfSearch = false; 247 cifsFile->srch_inf.endOfSearch = false;
241 248 cifsFile->tlink = cifs_get_tlink(tlink);
242 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
243 if (cifs_sb == NULL)
244 return -EINVAL;
245
246 pTcon = cifs_sb->tcon;
247 if (pTcon == NULL)
248 return -EINVAL;
249 249
250 full_path = build_path_from_dentry(file->f_path.dentry); 250 full_path = build_path_from_dentry(file->f_path.dentry);
251 251 if (full_path == NULL) {
252 if (full_path == NULL) 252 rc = -ENOMEM;
253 return -ENOMEM; 253 goto error_exit;
254 }
254 255
255 cFYI(1, "Full path: %s start at: %lld", full_path, file->f_pos); 256 cFYI(1, "Full path: %s start at: %lld", full_path, file->f_pos);
256 257
@@ -283,7 +284,9 @@ ffirst_retry:
283 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM; 284 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
284 goto ffirst_retry; 285 goto ffirst_retry;
285 } 286 }
287error_exit:
286 kfree(full_path); 288 kfree(full_path);
289 cifs_put_tlink(tlink);
287 return rc; 290 return rc;
288} 291}
289 292
@@ -738,6 +741,15 @@ static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir,
738 cifs_autodisable_serverino(cifs_sb); 741 cifs_autodisable_serverino(cifs_sb);
739 } 742 }
740 743
744 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) &&
745 CIFSCouldBeMFSymlink(&fattr))
746 /*
747 * trying to get the type and mode can be slow,
748 * so just call those regular files for now, and mark
749 * for reval
750 */
751 fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
752
741 ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid); 753 ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid);
742 tmp_dentry = cifs_readdir_lookup(file->f_dentry, &qstring, &fattr); 754 tmp_dentry = cifs_readdir_lookup(file->f_dentry, &qstring, &fattr);
743 755
@@ -777,9 +789,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
777 xid = GetXid(); 789 xid = GetXid();
778 790
779 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 791 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
780 pTcon = cifs_sb->tcon;
781 if (pTcon == NULL)
782 return -EINVAL;
783 792
784 switch ((int) file->f_pos) { 793 switch ((int) file->f_pos) {
785 case 0: 794 case 0:
@@ -829,6 +838,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
829 CIFSFindClose(xid, pTcon, cifsFile->netfid); 838 CIFSFindClose(xid, pTcon, cifsFile->netfid);
830 } */ 839 } */
831 840
841 pTcon = tlink_tcon(cifsFile->tlink);
832 rc = find_cifs_entry(xid, pTcon, file, 842 rc = find_cifs_entry(xid, pTcon, file,
833 &current_entry, &num_to_fill); 843 &current_entry, &num_to_fill);
834 if (rc) { 844 if (rc) {
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 0a57cb7db5dd..c926e6c7c0c6 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -383,6 +383,9 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft,
383static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, 383static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
384 struct cifsSesInfo *ses) 384 struct cifsSesInfo *ses)
385{ 385{
386 unsigned int tioffset; /* challenge message target info area */
387 unsigned int tilen; /* challenge message target info area length */
388
386 CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr; 389 CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr;
387 390
388 if (blob_len < sizeof(CHALLENGE_MESSAGE)) { 391 if (blob_len < sizeof(CHALLENGE_MESSAGE)) {
@@ -405,6 +408,19 @@ static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
405 /* BB spec says that if AvId field of MsvAvTimestamp is populated then 408 /* BB spec says that if AvId field of MsvAvTimestamp is populated then
406 we must set the MIC field of the AUTHENTICATE_MESSAGE */ 409 we must set the MIC field of the AUTHENTICATE_MESSAGE */
407 410
411 tioffset = cpu_to_le16(pblob->TargetInfoArray.BufferOffset);
412 tilen = cpu_to_le16(pblob->TargetInfoArray.Length);
413 ses->tilen = tilen;
414 if (ses->tilen) {
415 ses->tiblob = kmalloc(tilen, GFP_KERNEL);
416 if (!ses->tiblob) {
417 cERROR(1, "Challenge target info allocation failure");
418 ses->tilen = 0;
419 return -ENOMEM;
420 }
421 memcpy(ses->tiblob, bcc_ptr + tioffset, ses->tilen);
422 }
423
408 return 0; 424 return 0;
409} 425}
410 426
@@ -425,7 +441,7 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
425 /* BB is NTLMV2 session security format easier to use here? */ 441 /* BB is NTLMV2 session security format easier to use here? */
426 flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET | 442 flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET |
427 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | 443 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
428 NTLMSSP_NEGOTIATE_NT_ONLY | NTLMSSP_NEGOTIATE_NTLM; 444 NTLMSSP_NEGOTIATE_NTLM;
429 if (ses->server->secMode & 445 if (ses->server->secMode &
430 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 446 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
431 flags |= NTLMSSP_NEGOTIATE_SIGN; 447 flags |= NTLMSSP_NEGOTIATE_SIGN;
@@ -449,12 +465,14 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
449 This function returns the length of the data in the blob */ 465 This function returns the length of the data in the blob */
450static int build_ntlmssp_auth_blob(unsigned char *pbuffer, 466static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
451 struct cifsSesInfo *ses, 467 struct cifsSesInfo *ses,
452 const struct nls_table *nls_cp, bool first) 468 const struct nls_table *nls_cp)
453{ 469{
470 int rc;
471 unsigned int size;
454 AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer; 472 AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer;
455 __u32 flags; 473 __u32 flags;
456 unsigned char *tmp; 474 unsigned char *tmp;
457 char ntlm_session_key[CIFS_SESS_KEY_SIZE]; 475 struct ntlmv2_resp ntlmv2_response = {};
458 476
459 memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8); 477 memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
460 sec_blob->MessageType = NtLmAuthenticate; 478 sec_blob->MessageType = NtLmAuthenticate;
@@ -462,7 +480,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
462 flags = NTLMSSP_NEGOTIATE_56 | 480 flags = NTLMSSP_NEGOTIATE_56 |
463 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO | 481 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
464 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | 482 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
465 NTLMSSP_NEGOTIATE_NT_ONLY | NTLMSSP_NEGOTIATE_NTLM; 483 NTLMSSP_NEGOTIATE_NTLM;
466 if (ses->server->secMode & 484 if (ses->server->secMode &
467 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 485 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
468 flags |= NTLMSSP_NEGOTIATE_SIGN; 486 flags |= NTLMSSP_NEGOTIATE_SIGN;
@@ -477,19 +495,26 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
477 sec_blob->LmChallengeResponse.Length = 0; 495 sec_blob->LmChallengeResponse.Length = 0;
478 sec_blob->LmChallengeResponse.MaximumLength = 0; 496 sec_blob->LmChallengeResponse.MaximumLength = 0;
479 497
480 /* calculate session key, BB what about adding similar ntlmv2 path? */
481 SMBNTencrypt(ses->password, ses->server->cryptKey, ntlm_session_key);
482 if (first)
483 cifs_calculate_mac_key(&ses->server->mac_signing_key,
484 ntlm_session_key, ses->password);
485
486 memcpy(tmp, ntlm_session_key, CIFS_SESS_KEY_SIZE);
487 sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer); 498 sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer);
488 sec_blob->NtChallengeResponse.Length = cpu_to_le16(CIFS_SESS_KEY_SIZE); 499 rc = setup_ntlmv2_rsp(ses, (char *)&ntlmv2_response, nls_cp);
489 sec_blob->NtChallengeResponse.MaximumLength = 500 if (rc) {
490 cpu_to_le16(CIFS_SESS_KEY_SIZE); 501 cERROR(1, "Error %d during NTLMSSP authentication", rc);
502 goto setup_ntlmv2_ret;
503 }
504 size = sizeof(struct ntlmv2_resp);
505 memcpy(tmp, (char *)&ntlmv2_response, size);
506 tmp += size;
507 if (ses->tilen > 0) {
508 memcpy(tmp, ses->tiblob, ses->tilen);
509 tmp += ses->tilen;
510 }
491 511
492 tmp += CIFS_SESS_KEY_SIZE; 512 sec_blob->NtChallengeResponse.Length = cpu_to_le16(size + ses->tilen);
513 sec_blob->NtChallengeResponse.MaximumLength =
514 cpu_to_le16(size + ses->tilen);
515 kfree(ses->tiblob);
516 ses->tiblob = NULL;
517 ses->tilen = 0;
493 518
494 if (ses->domainName == NULL) { 519 if (ses->domainName == NULL) {
495 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); 520 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
@@ -501,7 +526,6 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
501 len = cifs_strtoUCS((__le16 *)tmp, ses->domainName, 526 len = cifs_strtoUCS((__le16 *)tmp, ses->domainName,
502 MAX_USERNAME_SIZE, nls_cp); 527 MAX_USERNAME_SIZE, nls_cp);
503 len *= 2; /* unicode is 2 bytes each */ 528 len *= 2; /* unicode is 2 bytes each */
504 len += 2; /* trailing null */
505 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); 529 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
506 sec_blob->DomainName.Length = cpu_to_le16(len); 530 sec_blob->DomainName.Length = cpu_to_le16(len);
507 sec_blob->DomainName.MaximumLength = cpu_to_le16(len); 531 sec_blob->DomainName.MaximumLength = cpu_to_le16(len);
@@ -518,7 +542,6 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
518 len = cifs_strtoUCS((__le16 *)tmp, ses->userName, 542 len = cifs_strtoUCS((__le16 *)tmp, ses->userName,
519 MAX_USERNAME_SIZE, nls_cp); 543 MAX_USERNAME_SIZE, nls_cp);
520 len *= 2; /* unicode is 2 bytes each */ 544 len *= 2; /* unicode is 2 bytes each */
521 len += 2; /* trailing null */
522 sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer); 545 sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
523 sec_blob->UserName.Length = cpu_to_le16(len); 546 sec_blob->UserName.Length = cpu_to_le16(len);
524 sec_blob->UserName.MaximumLength = cpu_to_le16(len); 547 sec_blob->UserName.MaximumLength = cpu_to_le16(len);
@@ -533,6 +556,8 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
533 sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer); 556 sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
534 sec_blob->SessionKey.Length = 0; 557 sec_blob->SessionKey.Length = 0;
535 sec_blob->SessionKey.MaximumLength = 0; 558 sec_blob->SessionKey.MaximumLength = 0;
559
560setup_ntlmv2_ret:
536 return tmp - pbuffer; 561 return tmp - pbuffer;
537} 562}
538 563
@@ -545,19 +570,6 @@ static void setup_ntlmssp_neg_req(SESSION_SETUP_ANDX *pSMB,
545 570
546 return; 571 return;
547} 572}
548
549static int setup_ntlmssp_auth_req(SESSION_SETUP_ANDX *pSMB,
550 struct cifsSesInfo *ses,
551 const struct nls_table *nls, bool first_time)
552{
553 int bloblen;
554
555 bloblen = build_ntlmssp_auth_blob(&pSMB->req.SecurityBlob[0], ses, nls,
556 first_time);
557 pSMB->req.SecurityBlobLength = cpu_to_le16(bloblen);
558
559 return bloblen;
560}
561#endif 573#endif
562 574
563int 575int
@@ -580,6 +592,8 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
580 struct key *spnego_key = NULL; 592 struct key *spnego_key = NULL;
581 __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */ 593 __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */
582 bool first_time; 594 bool first_time;
595 int blob_len;
596 char *ntlmsspblob = NULL;
583 597
584 if (ses == NULL) 598 if (ses == NULL)
585 return -EINVAL; 599 return -EINVAL;
@@ -690,7 +704,7 @@ ssetup_ntlmssp_authenticate:
690 704
691 if (first_time) /* should this be moved into common code 705 if (first_time) /* should this be moved into common code
692 with similar ntlmv2 path? */ 706 with similar ntlmv2 path? */
693 cifs_calculate_mac_key(&ses->server->mac_signing_key, 707 cifs_calculate_session_key(&ses->server->session_key,
694 ntlm_session_key, ses->password); 708 ntlm_session_key, ses->password);
695 /* copy session key */ 709 /* copy session key */
696 710
@@ -725,16 +739,31 @@ ssetup_ntlmssp_authenticate:
725 pSMB->req_no_secext.CaseInsensitivePasswordLength = 0; 739 pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
726 /* cpu_to_le16(LM2_SESS_KEY_SIZE); */ 740 /* cpu_to_le16(LM2_SESS_KEY_SIZE); */
727 741
728 pSMB->req_no_secext.CaseSensitivePasswordLength =
729 cpu_to_le16(sizeof(struct ntlmv2_resp));
730
731 /* calculate session key */ 742 /* calculate session key */
732 setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp); 743 rc = setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp);
733 /* FIXME: calculate MAC key */ 744 if (rc) {
745 cERROR(1, "Error %d during NTLMv2 authentication", rc);
746 kfree(v2_sess_key);
747 goto ssetup_exit;
748 }
734 memcpy(bcc_ptr, (char *)v2_sess_key, 749 memcpy(bcc_ptr, (char *)v2_sess_key,
735 sizeof(struct ntlmv2_resp)); 750 sizeof(struct ntlmv2_resp));
736 bcc_ptr += sizeof(struct ntlmv2_resp); 751 bcc_ptr += sizeof(struct ntlmv2_resp);
737 kfree(v2_sess_key); 752 kfree(v2_sess_key);
753 /* set case sensitive password length after tilen may get
754 * assigned, tilen is 0 otherwise.
755 */
756 pSMB->req_no_secext.CaseSensitivePasswordLength =
757 cpu_to_le16(sizeof(struct ntlmv2_resp) + ses->tilen);
758 if (ses->tilen > 0) {
759 memcpy(bcc_ptr, ses->tiblob, ses->tilen);
760 bcc_ptr += ses->tilen;
761 /* we never did allocate ses->domainName to free */
762 kfree(ses->tiblob);
763 ses->tiblob = NULL;
764 ses->tilen = 0;
765 }
766
738 if (ses->capabilities & CAP_UNICODE) { 767 if (ses->capabilities & CAP_UNICODE) {
739 if (iov[0].iov_len % 2) { 768 if (iov[0].iov_len % 2) {
740 *bcc_ptr = 0; 769 *bcc_ptr = 0;
@@ -765,15 +794,15 @@ ssetup_ntlmssp_authenticate:
765 } 794 }
766 /* bail out if key is too long */ 795 /* bail out if key is too long */
767 if (msg->sesskey_len > 796 if (msg->sesskey_len >
768 sizeof(ses->server->mac_signing_key.data.krb5)) { 797 sizeof(ses->server->session_key.data.krb5)) {
769 cERROR(1, "Kerberos signing key too long (%u bytes)", 798 cERROR(1, "Kerberos signing key too long (%u bytes)",
770 msg->sesskey_len); 799 msg->sesskey_len);
771 rc = -EOVERFLOW; 800 rc = -EOVERFLOW;
772 goto ssetup_exit; 801 goto ssetup_exit;
773 } 802 }
774 if (first_time) { 803 if (first_time) {
775 ses->server->mac_signing_key.len = msg->sesskey_len; 804 ses->server->session_key.len = msg->sesskey_len;
776 memcpy(ses->server->mac_signing_key.data.krb5, 805 memcpy(ses->server->session_key.data.krb5,
777 msg->data, msg->sesskey_len); 806 msg->data, msg->sesskey_len);
778 } 807 }
779 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; 808 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
@@ -815,12 +844,28 @@ ssetup_ntlmssp_authenticate:
815 if (phase == NtLmNegotiate) { 844 if (phase == NtLmNegotiate) {
816 setup_ntlmssp_neg_req(pSMB, ses); 845 setup_ntlmssp_neg_req(pSMB, ses);
817 iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE); 846 iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE);
847 iov[1].iov_base = &pSMB->req.SecurityBlob[0];
818 } else if (phase == NtLmAuthenticate) { 848 } else if (phase == NtLmAuthenticate) {
819 int blob_len; 849 /* 5 is an empirical value, large enought to
820 blob_len = setup_ntlmssp_auth_req(pSMB, ses, 850 * hold authenticate message, max 10 of
821 nls_cp, 851 * av paris, doamin,user,workstation mames,
822 first_time); 852 * flags etc..
853 */
854 ntlmsspblob = kmalloc(
855 5*sizeof(struct _AUTHENTICATE_MESSAGE),
856 GFP_KERNEL);
857 if (!ntlmsspblob) {
858 cERROR(1, "Can't allocate NTLMSSP");
859 rc = -ENOMEM;
860 goto ssetup_exit;
861 }
862
863 blob_len = build_ntlmssp_auth_blob(ntlmsspblob,
864 ses, nls_cp);
823 iov[1].iov_len = blob_len; 865 iov[1].iov_len = blob_len;
866 iov[1].iov_base = ntlmsspblob;
867 pSMB->req.SecurityBlobLength =
868 cpu_to_le16(blob_len);
824 /* Make sure that we tell the server that we 869 /* Make sure that we tell the server that we
825 are using the uid that it just gave us back 870 are using the uid that it just gave us back
826 on the response (challenge) */ 871 on the response (challenge) */
@@ -830,7 +875,6 @@ ssetup_ntlmssp_authenticate:
830 rc = -ENOSYS; 875 rc = -ENOSYS;
831 goto ssetup_exit; 876 goto ssetup_exit;
832 } 877 }
833 iov[1].iov_base = &pSMB->req.SecurityBlob[0];
834 /* unicode strings must be word aligned */ 878 /* unicode strings must be word aligned */
835 if ((iov[0].iov_len + iov[1].iov_len) % 2) { 879 if ((iov[0].iov_len + iov[1].iov_len) % 2) {
836 *bcc_ptr = 0; 880 *bcc_ptr = 0;
@@ -931,6 +975,8 @@ ssetup_exit:
931 key_put(spnego_key); 975 key_put(spnego_key);
932 } 976 }
933 kfree(str_area); 977 kfree(str_area);
978 kfree(ntlmsspblob);
979 ntlmsspblob = NULL;
934 if (resp_buf_type == CIFS_SMALL_BUFFER) { 980 if (resp_buf_type == CIFS_SMALL_BUFFER) {
935 cFYI(1, "ssetup freeing small buf %p", iov[0].iov_base); 981 cFYI(1, "ssetup freeing small buf %p", iov[0].iov_base);
936 cifs_small_buf_release(iov[0].iov_base); 982 cifs_small_buf_release(iov[0].iov_base);
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 82f78c4d6978..a66c91eb6eb4 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -543,7 +543,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
543 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 543 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
544 SECMODE_SIGN_ENABLED))) { 544 SECMODE_SIGN_ENABLED))) {
545 rc = cifs_verify_signature(midQ->resp_buf, 545 rc = cifs_verify_signature(midQ->resp_buf,
546 &ses->server->mac_signing_key, 546 &ses->server->session_key,
547 midQ->sequence_number+1); 547 midQ->sequence_number+1);
548 if (rc) { 548 if (rc) {
549 cERROR(1, "Unexpected SMB signature"); 549 cERROR(1, "Unexpected SMB signature");
@@ -731,7 +731,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
731 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 731 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
732 SECMODE_SIGN_ENABLED))) { 732 SECMODE_SIGN_ENABLED))) {
733 rc = cifs_verify_signature(out_buf, 733 rc = cifs_verify_signature(out_buf,
734 &ses->server->mac_signing_key, 734 &ses->server->session_key,
735 midQ->sequence_number+1); 735 midQ->sequence_number+1);
736 if (rc) { 736 if (rc) {
737 cERROR(1, "Unexpected SMB signature"); 737 cERROR(1, "Unexpected SMB signature");
@@ -981,7 +981,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
981 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 981 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
982 SECMODE_SIGN_ENABLED))) { 982 SECMODE_SIGN_ENABLED))) {
983 rc = cifs_verify_signature(out_buf, 983 rc = cifs_verify_signature(out_buf,
984 &ses->server->mac_signing_key, 984 &ses->server->session_key,
985 midQ->sequence_number+1); 985 midQ->sequence_number+1);
986 if (rc) { 986 if (rc) {
987 cERROR(1, "Unexpected SMB signature"); 987 cERROR(1, "Unexpected SMB signature");
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
index a1509207bfa6..a264b744bb41 100644
--- a/fs/cifs/xattr.c
+++ b/fs/cifs/xattr.c
@@ -47,9 +47,10 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name)
47#ifdef CONFIG_CIFS_XATTR 47#ifdef CONFIG_CIFS_XATTR
48 int xid; 48 int xid;
49 struct cifs_sb_info *cifs_sb; 49 struct cifs_sb_info *cifs_sb;
50 struct tcon_link *tlink;
50 struct cifsTconInfo *pTcon; 51 struct cifsTconInfo *pTcon;
51 struct super_block *sb; 52 struct super_block *sb;
52 char *full_path; 53 char *full_path = NULL;
53 54
54 if (direntry == NULL) 55 if (direntry == NULL)
55 return -EIO; 56 return -EIO;
@@ -58,16 +59,19 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name)
58 sb = direntry->d_inode->i_sb; 59 sb = direntry->d_inode->i_sb;
59 if (sb == NULL) 60 if (sb == NULL)
60 return -EIO; 61 return -EIO;
61 xid = GetXid();
62 62
63 cifs_sb = CIFS_SB(sb); 63 cifs_sb = CIFS_SB(sb);
64 pTcon = cifs_sb->tcon; 64 tlink = cifs_sb_tlink(cifs_sb);
65 if (IS_ERR(tlink))
66 return PTR_ERR(tlink);
67 pTcon = tlink_tcon(tlink);
68
69 xid = GetXid();
65 70
66 full_path = build_path_from_dentry(direntry); 71 full_path = build_path_from_dentry(direntry);
67 if (full_path == NULL) { 72 if (full_path == NULL) {
68 rc = -ENOMEM; 73 rc = -ENOMEM;
69 FreeXid(xid); 74 goto remove_ea_exit;
70 return rc;
71 } 75 }
72 if (ea_name == NULL) { 76 if (ea_name == NULL) {
73 cFYI(1, "Null xattr names not supported"); 77 cFYI(1, "Null xattr names not supported");
@@ -91,6 +95,7 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name)
91remove_ea_exit: 95remove_ea_exit:
92 kfree(full_path); 96 kfree(full_path);
93 FreeXid(xid); 97 FreeXid(xid);
98 cifs_put_tlink(tlink);
94#endif 99#endif
95 return rc; 100 return rc;
96} 101}
@@ -102,6 +107,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
102#ifdef CONFIG_CIFS_XATTR 107#ifdef CONFIG_CIFS_XATTR
103 int xid; 108 int xid;
104 struct cifs_sb_info *cifs_sb; 109 struct cifs_sb_info *cifs_sb;
110 struct tcon_link *tlink;
105 struct cifsTconInfo *pTcon; 111 struct cifsTconInfo *pTcon;
106 struct super_block *sb; 112 struct super_block *sb;
107 char *full_path; 113 char *full_path;
@@ -113,16 +119,19 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
113 sb = direntry->d_inode->i_sb; 119 sb = direntry->d_inode->i_sb;
114 if (sb == NULL) 120 if (sb == NULL)
115 return -EIO; 121 return -EIO;
116 xid = GetXid();
117 122
118 cifs_sb = CIFS_SB(sb); 123 cifs_sb = CIFS_SB(sb);
119 pTcon = cifs_sb->tcon; 124 tlink = cifs_sb_tlink(cifs_sb);
125 if (IS_ERR(tlink))
126 return PTR_ERR(tlink);
127 pTcon = tlink_tcon(tlink);
128
129 xid = GetXid();
120 130
121 full_path = build_path_from_dentry(direntry); 131 full_path = build_path_from_dentry(direntry);
122 if (full_path == NULL) { 132 if (full_path == NULL) {
123 rc = -ENOMEM; 133 rc = -ENOMEM;
124 FreeXid(xid); 134 goto set_ea_exit;
125 return rc;
126 } 135 }
127 /* return dos attributes as pseudo xattr */ 136 /* return dos attributes as pseudo xattr */
128 /* return alt name if available as pseudo attr */ 137 /* return alt name if available as pseudo attr */
@@ -132,9 +141,8 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
132 returns as xattrs */ 141 returns as xattrs */
133 if (value_size > MAX_EA_VALUE_SIZE) { 142 if (value_size > MAX_EA_VALUE_SIZE) {
134 cFYI(1, "size of EA value too large"); 143 cFYI(1, "size of EA value too large");
135 kfree(full_path); 144 rc = -EOPNOTSUPP;
136 FreeXid(xid); 145 goto set_ea_exit;
137 return -EOPNOTSUPP;
138 } 146 }
139 147
140 if (ea_name == NULL) { 148 if (ea_name == NULL) {
@@ -198,6 +206,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
198set_ea_exit: 206set_ea_exit:
199 kfree(full_path); 207 kfree(full_path);
200 FreeXid(xid); 208 FreeXid(xid);
209 cifs_put_tlink(tlink);
201#endif 210#endif
202 return rc; 211 return rc;
203} 212}
@@ -209,6 +218,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
209#ifdef CONFIG_CIFS_XATTR 218#ifdef CONFIG_CIFS_XATTR
210 int xid; 219 int xid;
211 struct cifs_sb_info *cifs_sb; 220 struct cifs_sb_info *cifs_sb;
221 struct tcon_link *tlink;
212 struct cifsTconInfo *pTcon; 222 struct cifsTconInfo *pTcon;
213 struct super_block *sb; 223 struct super_block *sb;
214 char *full_path; 224 char *full_path;
@@ -221,16 +231,18 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
221 if (sb == NULL) 231 if (sb == NULL)
222 return -EIO; 232 return -EIO;
223 233
224 xid = GetXid();
225
226 cifs_sb = CIFS_SB(sb); 234 cifs_sb = CIFS_SB(sb);
227 pTcon = cifs_sb->tcon; 235 tlink = cifs_sb_tlink(cifs_sb);
236 if (IS_ERR(tlink))
237 return PTR_ERR(tlink);
238 pTcon = tlink_tcon(tlink);
239
240 xid = GetXid();
228 241
229 full_path = build_path_from_dentry(direntry); 242 full_path = build_path_from_dentry(direntry);
230 if (full_path == NULL) { 243 if (full_path == NULL) {
231 rc = -ENOMEM; 244 rc = -ENOMEM;
232 FreeXid(xid); 245 goto get_ea_exit;
233 return rc;
234 } 246 }
235 /* return dos attributes as pseudo xattr */ 247 /* return dos attributes as pseudo xattr */
236 /* return alt name if available as pseudo attr */ 248 /* return alt name if available as pseudo attr */
@@ -323,6 +335,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
323get_ea_exit: 335get_ea_exit:
324 kfree(full_path); 336 kfree(full_path);
325 FreeXid(xid); 337 FreeXid(xid);
338 cifs_put_tlink(tlink);
326#endif 339#endif
327 return rc; 340 return rc;
328} 341}
@@ -333,6 +346,7 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size)
333#ifdef CONFIG_CIFS_XATTR 346#ifdef CONFIG_CIFS_XATTR
334 int xid; 347 int xid;
335 struct cifs_sb_info *cifs_sb; 348 struct cifs_sb_info *cifs_sb;
349 struct tcon_link *tlink;
336 struct cifsTconInfo *pTcon; 350 struct cifsTconInfo *pTcon;
337 struct super_block *sb; 351 struct super_block *sb;
338 char *full_path; 352 char *full_path;
@@ -346,18 +360,20 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size)
346 return -EIO; 360 return -EIO;
347 361
348 cifs_sb = CIFS_SB(sb); 362 cifs_sb = CIFS_SB(sb);
349 pTcon = cifs_sb->tcon;
350
351 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) 363 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
352 return -EOPNOTSUPP; 364 return -EOPNOTSUPP;
353 365
366 tlink = cifs_sb_tlink(cifs_sb);
367 if (IS_ERR(tlink))
368 return PTR_ERR(tlink);
369 pTcon = tlink_tcon(tlink);
370
354 xid = GetXid(); 371 xid = GetXid();
355 372
356 full_path = build_path_from_dentry(direntry); 373 full_path = build_path_from_dentry(direntry);
357 if (full_path == NULL) { 374 if (full_path == NULL) {
358 rc = -ENOMEM; 375 rc = -ENOMEM;
359 FreeXid(xid); 376 goto list_ea_exit;
360 return rc;
361 } 377 }
362 /* return dos attributes as pseudo xattr */ 378 /* return dos attributes as pseudo xattr */
363 /* return alt name if available as pseudo attr */ 379 /* return alt name if available as pseudo attr */
@@ -370,8 +386,10 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size)
370 cifs_sb->mnt_cifs_flags & 386 cifs_sb->mnt_cifs_flags &
371 CIFS_MOUNT_MAP_SPECIAL_CHR); 387 CIFS_MOUNT_MAP_SPECIAL_CHR);
372 388
389list_ea_exit:
373 kfree(full_path); 390 kfree(full_path);
374 FreeXid(xid); 391 FreeXid(xid);
392 cifs_put_tlink(tlink);
375#endif 393#endif
376 return rc; 394 return rc;
377} 395}