aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-10-22 20:52:29 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-22 20:52:29 -0400
commitd2ecad9faca2221ae6f664f146f0dcae661bf39d (patch)
tree9a13aabd0925e41586a292d34990ac2df73c34b2 /fs/cifs
parentc70b5296e775cde46cfcb2d860ba160108a5ec7a (diff)
parentcdff08e76612e53580139653403aedea979aa639 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6: (56 commits) [CIFS] move close processing from cifs_close to cifsFileInfo_put cifs: convert cifs_tcp_ses_lock from a rwlock to a spinlock cifs: cancel_delayed_work() + flush_scheduled_work() -> cancel_delayed_work_sync() Clean up two declarations of blob_len cifs: move cifsFileInfo_put to file.c cifs: convert GlobalSMBSeslock from a rwlock to regular spinlock [CIFS] Fix minor checkpatch warning and update cifs version cifs: move cifs_new_fileinfo to file.c cifs: eliminate pfile pointer from cifsFileInfo cifs: cifs_write argument change and cleanup cifs: clean up cifs_reopen_file cifs: eliminate the inode argument from cifs_new_fileinfo cifs: eliminate oflags option from cifs_new_fileinfo cifs: fix flags handling in cifs_posix_open cifs: eliminate cifs_posix_open_inode_helper cifs: handle FindFirst failure gracefully NTLM authentication and signing - Calculate auth response per smb session cifs: don't use vfsmount to pin superblock for oplock breaks cifs: keep dentry reference in cifsFileInfo instead of inode reference cifs: on multiuser mount, set ownership to current_fsuid/current_fsgid (try #7) ... Fix up trivial conflict in fs/cifs/cifsfs.c due to added/removed header files
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/README5
-rw-r--r--fs/cifs/cifs_debug.c12
-rw-r--r--fs/cifs/cifs_debug.h2
-rw-r--r--fs/cifs/cifs_dfs_ref.c24
-rw-r--r--fs/cifs/cifs_fs_sb.h13
-rw-r--r--fs/cifs/cifsacl.c46
-rw-r--r--fs/cifs/cifsencrypt.c214
-rw-r--r--fs/cifs/cifsfs.c92
-rw-r--r--fs/cifs/cifsfs.h10
-rw-r--r--fs/cifs/cifsglob.h91
-rw-r--r--fs/cifs/cifspdu.h1
-rw-r--r--fs/cifs/cifsproto.h22
-rw-r--r--fs/cifs/cifssmb.c30
-rw-r--r--fs/cifs/cn_cifs.h37
-rw-r--r--fs/cifs/connect.c534
-rw-r--r--fs/cifs/dir.c212
-rw-r--r--fs/cifs/file.c791
-rw-r--r--fs/cifs/fscache.c13
-rw-r--r--fs/cifs/inode.c237
-rw-r--r--fs/cifs/ioctl.c17
-rw-r--r--fs/cifs/link.c372
-rw-r--r--fs/cifs/misc.c32
-rw-r--r--fs/cifs/ntlmssp.h15
-rw-r--r--fs/cifs/readdir.c79
-rw-r--r--fs/cifs/sess.c167
-rw-r--r--fs/cifs/transport.c6
-rw-r--r--fs/cifs/xattr.c60
27 files changed, 2091 insertions, 1043 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.c b/fs/cifs/cifs_debug.c
index eb1ba493489f..103ab8b605b0 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -148,7 +148,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
148 seq_printf(m, "Servers:"); 148 seq_printf(m, "Servers:");
149 149
150 i = 0; 150 i = 0;
151 read_lock(&cifs_tcp_ses_lock); 151 spin_lock(&cifs_tcp_ses_lock);
152 list_for_each(tmp1, &cifs_tcp_ses_list) { 152 list_for_each(tmp1, &cifs_tcp_ses_list) {
153 server = list_entry(tmp1, struct TCP_Server_Info, 153 server = list_entry(tmp1, struct TCP_Server_Info,
154 tcp_ses_list); 154 tcp_ses_list);
@@ -230,7 +230,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
230 spin_unlock(&GlobalMid_Lock); 230 spin_unlock(&GlobalMid_Lock);
231 } 231 }
232 } 232 }
233 read_unlock(&cifs_tcp_ses_lock); 233 spin_unlock(&cifs_tcp_ses_lock);
234 seq_putc(m, '\n'); 234 seq_putc(m, '\n');
235 235
236 /* BB add code to dump additional info such as TCP session info now */ 236 /* BB add code to dump additional info such as TCP session info now */
@@ -270,7 +270,7 @@ static ssize_t cifs_stats_proc_write(struct file *file,
270 atomic_set(&totBufAllocCount, 0); 270 atomic_set(&totBufAllocCount, 0);
271 atomic_set(&totSmBufAllocCount, 0); 271 atomic_set(&totSmBufAllocCount, 0);
272#endif /* CONFIG_CIFS_STATS2 */ 272#endif /* CONFIG_CIFS_STATS2 */
273 read_lock(&cifs_tcp_ses_lock); 273 spin_lock(&cifs_tcp_ses_lock);
274 list_for_each(tmp1, &cifs_tcp_ses_list) { 274 list_for_each(tmp1, &cifs_tcp_ses_list) {
275 server = list_entry(tmp1, struct TCP_Server_Info, 275 server = list_entry(tmp1, struct TCP_Server_Info,
276 tcp_ses_list); 276 tcp_ses_list);
@@ -303,7 +303,7 @@ static ssize_t cifs_stats_proc_write(struct file *file,
303 } 303 }
304 } 304 }
305 } 305 }
306 read_unlock(&cifs_tcp_ses_lock); 306 spin_unlock(&cifs_tcp_ses_lock);
307 } 307 }
308 308
309 return count; 309 return count;
@@ -343,7 +343,7 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v)
343 GlobalCurrentXid, GlobalMaxActiveXid); 343 GlobalCurrentXid, GlobalMaxActiveXid);
344 344
345 i = 0; 345 i = 0;
346 read_lock(&cifs_tcp_ses_lock); 346 spin_lock(&cifs_tcp_ses_lock);
347 list_for_each(tmp1, &cifs_tcp_ses_list) { 347 list_for_each(tmp1, &cifs_tcp_ses_list) {
348 server = list_entry(tmp1, struct TCP_Server_Info, 348 server = list_entry(tmp1, struct TCP_Server_Info,
349 tcp_ses_list); 349 tcp_ses_list);
@@ -397,7 +397,7 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v)
397 } 397 }
398 } 398 }
399 } 399 }
400 read_unlock(&cifs_tcp_ses_lock); 400 spin_unlock(&cifs_tcp_ses_lock);
401 401
402 seq_putc(m, '\n'); 402 seq_putc(m, '\n');
403 return 0; 403 return 0;
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..c68a056f27fd 100644
--- a/fs/cifs/cifs_dfs_ref.c
+++ b/fs/cifs/cifs_dfs_ref.c
@@ -44,8 +44,7 @@ static void cifs_dfs_expire_automounts(struct work_struct *work)
44void cifs_dfs_release_automount_timer(void) 44void cifs_dfs_release_automount_timer(void)
45{ 45{
46 BUG_ON(!list_empty(&cifs_dfs_automount_list)); 46 BUG_ON(!list_empty(&cifs_dfs_automount_list));
47 cancel_delayed_work(&cifs_dfs_automount_task); 47 cancel_delayed_work_sync(&cifs_dfs_automount_task);
48 flush_scheduled_work();
49} 48}
50 49
51/** 50/**
@@ -306,6 +305,7 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
306 int xid, i; 305 int xid, i;
307 int rc = 0; 306 int rc = 0;
308 struct vfsmount *mnt = ERR_PTR(-ENOENT); 307 struct vfsmount *mnt = ERR_PTR(-ENOENT);
308 struct tcon_link *tlink;
309 309
310 cFYI(1, "in %s", __func__); 310 cFYI(1, "in %s", __func__);
311 BUG_ON(IS_ROOT(dentry)); 311 BUG_ON(IS_ROOT(dentry));
@@ -315,14 +315,6 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
315 dput(nd->path.dentry); 315 dput(nd->path.dentry);
316 nd->path.dentry = dget(dentry); 316 nd->path.dentry = dget(dentry);
317 317
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 /* 318 /*
327 * The MSDFS spec states that paths in DFS referral requests and 319 * The MSDFS spec states that paths in DFS referral requests and
328 * responses must be prefixed by a single '\' character instead of 320 * responses must be prefixed by a single '\' character instead of
@@ -335,10 +327,20 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
335 goto out_err; 327 goto out_err;
336 } 328 }
337 329
338 rc = get_dfs_path(xid, ses , full_path + 1, cifs_sb->local_nls, 330 cifs_sb = CIFS_SB(dentry->d_inode->i_sb);
331 tlink = cifs_sb_tlink(cifs_sb);
332 if (IS_ERR(tlink)) {
333 rc = PTR_ERR(tlink);
334 goto out_err;
335 }
336 ses = tlink_tcon(tlink)->ses;
337
338 rc = get_dfs_path(xid, ses, full_path + 1, cifs_sb->local_nls,
339 &num_referrals, &referrals, 339 &num_referrals, &referrals,
340 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 340 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
341 341
342 cifs_put_tlink(tlink);
343
342 for (i = 0; i < num_referrals; i++) { 344 for (i = 0; i < num_referrals; i++) {
343 int len; 345 int len;
344 dump_referral(referrals+i); 346 dump_referral(referrals+i);
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index 9e771450c3b8..525ba59a4105 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,23 +38,28 @@
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;
51 atomic_t active;
46 uid_t mnt_uid; 52 uid_t mnt_uid;
47 gid_t mnt_gid; 53 gid_t mnt_gid;
48 mode_t mnt_file_mode; 54 mode_t mnt_file_mode;
49 mode_t mnt_dir_mode; 55 mode_t mnt_dir_mode;
50 int mnt_cifs_flags; 56 unsigned int mnt_cifs_flags;
51 int prepathlen; 57 int prepathlen;
52 char *prepath; /* relative path under the share to mount to */ 58 char *prepath; /* relative path under the share to mount to */
53#ifdef CONFIG_CIFS_DFS_UPCALL 59#ifdef CONFIG_CIFS_DFS_UPCALL
54 char *mountdata; /* mount options received at mount time */ 60 char *mountdata; /* mount options received at mount time */
55#endif 61#endif
56 struct backing_dev_info bdi; 62 struct backing_dev_info bdi;
63 struct delayed_work prune_tlinks;
57}; 64};
58#endif /* _CIFS_FS_SB_H */ 65#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..7ac0056294cf 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,148 @@ 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/* Build a proper attribute value/target info pairs blob.
267 * Fill in netbios and dns domain name and workstation name
268 * and client time (total five av pairs and + one end of fields indicator.
269 * Allocate domain name which gets freed when session struct is deallocated.
270 */
271static int
272build_avpair_blob(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
273{
274 unsigned int dlen;
275 unsigned int wlen;
276 unsigned int size = 6 * sizeof(struct ntlmssp2_name);
277 __le64 curtime;
278 char *defdmname = "WORKGROUP";
279 unsigned char *blobptr;
280 struct ntlmssp2_name *attrptr;
281
282 if (!ses->domainName) {
283 ses->domainName = kstrdup(defdmname, GFP_KERNEL);
284 if (!ses->domainName)
285 return -ENOMEM;
286 }
287
288 dlen = strlen(ses->domainName);
289 wlen = strlen(ses->server->hostname);
290
291 /* The length of this blob is a size which is
292 * six times the size of a structure which holds name/size +
293 * two times the unicode length of a domain name +
294 * two times the unicode length of a server name +
295 * size of a timestamp (which is 8 bytes).
296 */
297 ses->tilen = size + 2 * (2 * dlen) + 2 * (2 * wlen) + 8;
298 ses->tiblob = kzalloc(ses->tilen, GFP_KERNEL);
299 if (!ses->tiblob) {
300 ses->tilen = 0;
301 cERROR(1, "Challenge target info allocation failure");
302 return -ENOMEM;
303 }
304
305 blobptr = ses->tiblob;
306 attrptr = (struct ntlmssp2_name *) blobptr;
307
308 attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_DOMAIN_NAME);
309 attrptr->length = cpu_to_le16(2 * dlen);
310 blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
311 cifs_strtoUCS((__le16 *)blobptr, ses->domainName, dlen, nls_cp);
312
313 blobptr += 2 * dlen;
314 attrptr = (struct ntlmssp2_name *) blobptr;
315
316 attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_COMPUTER_NAME);
317 attrptr->length = cpu_to_le16(2 * wlen);
318 blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
319 cifs_strtoUCS((__le16 *)blobptr, ses->server->hostname, wlen, nls_cp);
320
321 blobptr += 2 * wlen;
322 attrptr = (struct ntlmssp2_name *) blobptr;
323
324 attrptr->type = cpu_to_le16(NTLMSSP_AV_DNS_DOMAIN_NAME);
325 attrptr->length = cpu_to_le16(2 * dlen);
326 blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
327 cifs_strtoUCS((__le16 *)blobptr, ses->domainName, dlen, nls_cp);
328
329 blobptr += 2 * dlen;
330 attrptr = (struct ntlmssp2_name *) blobptr;
331
332 attrptr->type = cpu_to_le16(NTLMSSP_AV_DNS_COMPUTER_NAME);
333 attrptr->length = cpu_to_le16(2 * wlen);
334 blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
335 cifs_strtoUCS((__le16 *)blobptr, ses->server->hostname, wlen, nls_cp);
336
337 blobptr += 2 * wlen;
338 attrptr = (struct ntlmssp2_name *) blobptr;
339
340 attrptr->type = cpu_to_le16(NTLMSSP_AV_TIMESTAMP);
341 attrptr->length = cpu_to_le16(sizeof(__le64));
342 blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
343 curtime = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
344 memcpy(blobptr, &curtime, sizeof(__le64));
345
346 return 0;
347}
348
349/* Server has provided av pairs/target info in the type 2 challenge
350 * packet and we have plucked it and stored within smb session.
351 * We parse that blob here to find netbios domain name to be used
352 * as part of ntlmv2 authentication (in Target String), if not already
353 * specified on the command line.
354 * If this function returns without any error but without fetching
355 * domain name, authentication may fail against some server but
356 * may not fail against other (those who are not very particular
357 * about target string i.e. for some, just user name might suffice.
358 */
359static int
360find_domain_name(struct cifsSesInfo *ses)
361{
362 unsigned int attrsize;
363 unsigned int type;
364 unsigned int onesize = sizeof(struct ntlmssp2_name);
365 unsigned char *blobptr;
366 unsigned char *blobend;
367 struct ntlmssp2_name *attrptr;
368
369 if (!ses->tilen || !ses->tiblob)
370 return 0;
371
372 blobptr = ses->tiblob;
373 blobend = ses->tiblob + ses->tilen;
374
375 while (blobptr + onesize < blobend) {
376 attrptr = (struct ntlmssp2_name *) blobptr;
377 type = le16_to_cpu(attrptr->type);
378 if (type == NTLMSSP_AV_EOL)
379 break;
380 blobptr += 2; /* advance attr type */
381 attrsize = le16_to_cpu(attrptr->length);
382 blobptr += 2; /* advance attr size */
383 if (blobptr + attrsize > blobend)
384 break;
385 if (type == NTLMSSP_AV_NB_DOMAIN_NAME) {
386 if (!attrsize)
387 break;
388 if (!ses->domainName) {
389 struct nls_table *default_nls;
390 ses->domainName =
391 kmalloc(attrsize + 1, GFP_KERNEL);
392 if (!ses->domainName)
393 return -ENOMEM;
394 default_nls = load_nls_default();
395 cifs_from_ucs2(ses->domainName,
396 (__le16 *)blobptr, attrsize, attrsize,
397 default_nls, false);
398 unload_nls(default_nls);
399 break;
400 }
401 }
402 blobptr += attrsize; /* advance attr value */
403 }
404
405 return 0;
406}
407
265static int calc_ntlmv2_hash(struct cifsSesInfo *ses, 408static int calc_ntlmv2_hash(struct cifsSesInfo *ses,
266 const struct nls_table *nls_cp) 409 const struct nls_table *nls_cp)
267{ 410{
@@ -315,13 +458,14 @@ calc_exit_1:
315calc_exit_2: 458calc_exit_2:
316 /* BB FIXME what about bytes 24 through 40 of the signing key? 459 /* BB FIXME what about bytes 24 through 40 of the signing key?
317 compare with the NTLM example */ 460 compare with the NTLM example */
318 hmac_md5_final(ses->server->ntlmv2_hash, pctxt); 461 hmac_md5_final(ses->ntlmv2_hash, pctxt);
319 462
320 kfree(pctxt); 463 kfree(pctxt);
321 return rc; 464 return rc;
322} 465}
323 466
324void setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf, 467int
468setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf,
325 const struct nls_table *nls_cp) 469 const struct nls_table *nls_cp)
326{ 470{
327 int rc; 471 int rc;
@@ -333,25 +477,48 @@ void setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf,
333 buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 477 buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
334 get_random_bytes(&buf->client_chal, sizeof(buf->client_chal)); 478 get_random_bytes(&buf->client_chal, sizeof(buf->client_chal));
335 buf->reserved2 = 0; 479 buf->reserved2 = 0;
336 buf->names[0].type = cpu_to_le16(NTLMSSP_DOMAIN_TYPE); 480
337 buf->names[0].length = 0; 481 if (ses->server->secType == RawNTLMSSP) {
338 buf->names[1].type = 0; 482 if (!ses->domainName) {
339 buf->names[1].length = 0; 483 rc = find_domain_name(ses);
484 if (rc) {
485 cERROR(1, "error %d finding domain name", rc);
486 goto setup_ntlmv2_rsp_ret;
487 }
488 }
489 } else {
490 rc = build_avpair_blob(ses, nls_cp);
491 if (rc) {
492 cERROR(1, "error %d building av pair blob", rc);
493 return rc;
494 }
495 }
340 496
341 /* calculate buf->ntlmv2_hash */ 497 /* calculate buf->ntlmv2_hash */
342 rc = calc_ntlmv2_hash(ses, nls_cp); 498 rc = calc_ntlmv2_hash(ses, nls_cp);
343 if (rc) 499 if (rc) {
344 cERROR(1, "could not get v2 hash rc %d", rc); 500 cERROR(1, "could not get v2 hash rc %d", rc);
501 goto setup_ntlmv2_rsp_ret;
502 }
345 CalcNTLMv2_response(ses, resp_buf); 503 CalcNTLMv2_response(ses, resp_buf);
346 504
347 /* now calculate the MAC key for NTLMv2 */ 505 /* now calculate the session key for NTLMv2 */
348 hmac_md5_init_limK_to_64(ses->server->ntlmv2_hash, 16, &context); 506 hmac_md5_init_limK_to_64(ses->ntlmv2_hash, 16, &context);
349 hmac_md5_update(resp_buf, 16, &context); 507 hmac_md5_update(resp_buf, 16, &context);
350 hmac_md5_final(ses->server->mac_signing_key.data.ntlmv2.key, &context); 508 hmac_md5_final(ses->auth_key.data.ntlmv2.key, &context);
351 509
352 memcpy(&ses->server->mac_signing_key.data.ntlmv2.resp, resp_buf, 510 memcpy(&ses->auth_key.data.ntlmv2.resp, resp_buf,
353 sizeof(struct ntlmv2_resp)); 511 sizeof(struct ntlmv2_resp));
354 ses->server->mac_signing_key.len = 16 + sizeof(struct ntlmv2_resp); 512 ses->auth_key.len = 16 + sizeof(struct ntlmv2_resp);
513
514 return 0;
515
516setup_ntlmv2_rsp_ret:
517 kfree(ses->tiblob);
518 ses->tiblob = NULL;
519 ses->tilen = 0;
520
521 return rc;
355} 522}
356 523
357void CalcNTLMv2_response(const struct cifsSesInfo *ses, 524void CalcNTLMv2_response(const struct cifsSesInfo *ses,
@@ -359,12 +526,15 @@ void CalcNTLMv2_response(const struct cifsSesInfo *ses,
359{ 526{
360 struct HMACMD5Context context; 527 struct HMACMD5Context context;
361 /* rest of v2 struct already generated */ 528 /* rest of v2 struct already generated */
362 memcpy(v2_session_response + 8, ses->server->cryptKey, 8); 529 memcpy(v2_session_response + 8, ses->cryptKey, 8);
363 hmac_md5_init_limK_to_64(ses->server->ntlmv2_hash, 16, &context); 530 hmac_md5_init_limK_to_64(ses->ntlmv2_hash, 16, &context);
364 531
365 hmac_md5_update(v2_session_response+8, 532 hmac_md5_update(v2_session_response+8,
366 sizeof(struct ntlmv2_resp) - 8, &context); 533 sizeof(struct ntlmv2_resp) - 8, &context);
367 534
535 if (ses->tilen)
536 hmac_md5_update(ses->tiblob, ses->tilen, &context);
537
368 hmac_md5_final(v2_session_response, &context); 538 hmac_md5_final(v2_session_response, &context);
369/* cifs_dump_mem("v2_sess_rsp: ", v2_session_response, 32); */ 539/* cifs_dump_mem("v2_sess_rsp: ", v2_session_response, 32); */
370} 540}
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 50208c15309a..34371637f210 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -35,6 +35,7 @@
35#include <linux/delay.h> 35#include <linux/delay.h>
36#include <linux/kthread.h> 36#include <linux/kthread.h>
37#include <linux/freezer.h> 37#include <linux/freezer.h>
38#include <net/ipv6.h>
38#include "cifsfs.h" 39#include "cifsfs.h"
39#include "cifspdu.h" 40#include "cifspdu.h"
40#define DECLARE_GLOBALS_HERE 41#define DECLARE_GLOBALS_HERE
@@ -81,6 +82,24 @@ extern mempool_t *cifs_sm_req_poolp;
81extern mempool_t *cifs_req_poolp; 82extern mempool_t *cifs_req_poolp;
82extern mempool_t *cifs_mid_poolp; 83extern mempool_t *cifs_mid_poolp;
83 84
85void
86cifs_sb_active(struct super_block *sb)
87{
88 struct cifs_sb_info *server = CIFS_SB(sb);
89
90 if (atomic_inc_return(&server->active) == 1)
91 atomic_inc(&sb->s_active);
92}
93
94void
95cifs_sb_deactive(struct super_block *sb)
96{
97 struct cifs_sb_info *server = CIFS_SB(sb);
98
99 if (atomic_dec_and_test(&server->active))
100 deactivate_super(sb);
101}
102
84static int 103static int
85cifs_read_super(struct super_block *sb, void *data, 104cifs_read_super(struct super_block *sb, void *data,
86 const char *devname, int silent) 105 const char *devname, int silent)
@@ -96,6 +115,9 @@ cifs_read_super(struct super_block *sb, void *data,
96 if (cifs_sb == NULL) 115 if (cifs_sb == NULL)
97 return -ENOMEM; 116 return -ENOMEM;
98 117
118 spin_lock_init(&cifs_sb->tlink_tree_lock);
119 INIT_RADIX_TREE(&cifs_sb->tlink_tree, GFP_KERNEL);
120
99 rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); 121 rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY);
100 if (rc) { 122 if (rc) {
101 kfree(cifs_sb); 123 kfree(cifs_sb);
@@ -135,9 +157,6 @@ cifs_read_super(struct super_block *sb, void *data,
135 sb->s_magic = CIFS_MAGIC_NUMBER; 157 sb->s_magic = CIFS_MAGIC_NUMBER;
136 sb->s_op = &cifs_super_ops; 158 sb->s_op = &cifs_super_ops;
137 sb->s_bdi = &cifs_sb->bdi; 159 sb->s_bdi = &cifs_sb->bdi;
138/* if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512)
139 sb->s_blocksize =
140 cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */
141 sb->s_blocksize = CIFS_MAX_MSGSIZE; 160 sb->s_blocksize = CIFS_MAX_MSGSIZE;
142 sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */ 161 sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */
143 inode = cifs_root_iget(sb, ROOT_I); 162 inode = cifs_root_iget(sb, ROOT_I);
@@ -219,7 +238,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
219{ 238{
220 struct super_block *sb = dentry->d_sb; 239 struct super_block *sb = dentry->d_sb;
221 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 240 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
222 struct cifsTconInfo *tcon = cifs_sb->tcon; 241 struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
223 int rc = -EOPNOTSUPP; 242 int rc = -EOPNOTSUPP;
224 int xid; 243 int xid;
225 244
@@ -361,14 +380,36 @@ static int
361cifs_show_options(struct seq_file *s, struct vfsmount *m) 380cifs_show_options(struct seq_file *s, struct vfsmount *m)
362{ 381{
363 struct cifs_sb_info *cifs_sb = CIFS_SB(m->mnt_sb); 382 struct cifs_sb_info *cifs_sb = CIFS_SB(m->mnt_sb);
364 struct cifsTconInfo *tcon = cifs_sb->tcon; 383 struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
384 struct sockaddr *srcaddr;
385 srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr;
365 386
366 seq_printf(s, ",unc=%s", tcon->treeName); 387 seq_printf(s, ",unc=%s", tcon->treeName);
367 if (tcon->ses->userName) 388
389 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)
390 seq_printf(s, ",multiuser");
391 else if (tcon->ses->userName)
368 seq_printf(s, ",username=%s", tcon->ses->userName); 392 seq_printf(s, ",username=%s", tcon->ses->userName);
393
369 if (tcon->ses->domainName) 394 if (tcon->ses->domainName)
370 seq_printf(s, ",domain=%s", tcon->ses->domainName); 395 seq_printf(s, ",domain=%s", tcon->ses->domainName);
371 396
397 if (srcaddr->sa_family != AF_UNSPEC) {
398 struct sockaddr_in *saddr4;
399 struct sockaddr_in6 *saddr6;
400 saddr4 = (struct sockaddr_in *)srcaddr;
401 saddr6 = (struct sockaddr_in6 *)srcaddr;
402 if (srcaddr->sa_family == AF_INET6)
403 seq_printf(s, ",srcaddr=%pI6c",
404 &saddr6->sin6_addr);
405 else if (srcaddr->sa_family == AF_INET)
406 seq_printf(s, ",srcaddr=%pI4",
407 &saddr4->sin_addr.s_addr);
408 else
409 seq_printf(s, ",srcaddr=BAD-AF:%i",
410 (int)(srcaddr->sa_family));
411 }
412
372 seq_printf(s, ",uid=%d", cifs_sb->mnt_uid); 413 seq_printf(s, ",uid=%d", cifs_sb->mnt_uid);
373 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) 414 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
374 seq_printf(s, ",forceuid"); 415 seq_printf(s, ",forceuid");
@@ -417,6 +458,8 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
417 seq_printf(s, ",dynperm"); 458 seq_printf(s, ",dynperm");
418 if (m->mnt_sb->s_flags & MS_POSIXACL) 459 if (m->mnt_sb->s_flags & MS_POSIXACL)
419 seq_printf(s, ",acl"); 460 seq_printf(s, ",acl");
461 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
462 seq_printf(s, ",mfsymlinks");
420 463
421 seq_printf(s, ",rsize=%d", cifs_sb->rsize); 464 seq_printf(s, ",rsize=%d", cifs_sb->rsize);
422 seq_printf(s, ",wsize=%d", cifs_sb->wsize); 465 seq_printf(s, ",wsize=%d", cifs_sb->wsize);
@@ -432,20 +475,18 @@ static void cifs_umount_begin(struct super_block *sb)
432 if (cifs_sb == NULL) 475 if (cifs_sb == NULL)
433 return; 476 return;
434 477
435 tcon = cifs_sb->tcon; 478 tcon = cifs_sb_master_tcon(cifs_sb);
436 if (tcon == NULL)
437 return;
438 479
439 read_lock(&cifs_tcp_ses_lock); 480 spin_lock(&cifs_tcp_ses_lock);
440 if ((tcon->tc_count > 1) || (tcon->tidStatus == CifsExiting)) { 481 if ((tcon->tc_count > 1) || (tcon->tidStatus == CifsExiting)) {
441 /* we have other mounts to same share or we have 482 /* we have other mounts to same share or we have
442 already tried to force umount this and woken up 483 already tried to force umount this and woken up
443 all waiting network requests, nothing to do */ 484 all waiting network requests, nothing to do */
444 read_unlock(&cifs_tcp_ses_lock); 485 spin_unlock(&cifs_tcp_ses_lock);
445 return; 486 return;
446 } else if (tcon->tc_count == 1) 487 } else if (tcon->tc_count == 1)
447 tcon->tidStatus = CifsExiting; 488 tcon->tidStatus = CifsExiting;
448 read_unlock(&cifs_tcp_ses_lock); 489 spin_unlock(&cifs_tcp_ses_lock);
449 490
450 /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */ 491 /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */
451 /* cancel_notify_requests(tcon); */ 492 /* cancel_notify_requests(tcon); */
@@ -565,6 +606,7 @@ static int cifs_setlease(struct file *file, long arg, struct file_lock **lease)
565 /* note that this is called by vfs setlease with lock_flocks held 606 /* note that this is called by vfs setlease with lock_flocks held
566 to protect *lease from going away */ 607 to protect *lease from going away */
567 struct inode *inode = file->f_path.dentry->d_inode; 608 struct inode *inode = file->f_path.dentry->d_inode;
609 struct cifsFileInfo *cfile = file->private_data;
568 610
569 if (!(S_ISREG(inode->i_mode))) 611 if (!(S_ISREG(inode->i_mode)))
570 return -EINVAL; 612 return -EINVAL;
@@ -575,8 +617,8 @@ static int cifs_setlease(struct file *file, long arg, struct file_lock **lease)
575 ((arg == F_WRLCK) && 617 ((arg == F_WRLCK) &&
576 (CIFS_I(inode)->clientCanCacheAll))) 618 (CIFS_I(inode)->clientCanCacheAll)))
577 return generic_setlease(file, arg, lease); 619 return generic_setlease(file, arg, lease);
578 else if (CIFS_SB(inode->i_sb)->tcon->local_lease && 620 else if (tlink_tcon(cfile->tlink)->local_lease &&
579 !CIFS_I(inode)->clientCanCacheRead) 621 !CIFS_I(inode)->clientCanCacheRead)
580 /* If the server claims to support oplock on this 622 /* If the server claims to support oplock on this
581 file, then we still need to check oplock even 623 file, then we still need to check oplock even
582 if the local_lease mount option is set, but there 624 if the local_lease mount option is set, but there
@@ -895,8 +937,8 @@ init_cifs(void)
895 GlobalTotalActiveXid = 0; 937 GlobalTotalActiveXid = 0;
896 GlobalMaxActiveXid = 0; 938 GlobalMaxActiveXid = 0;
897 memset(Local_System_Name, 0, 15); 939 memset(Local_System_Name, 0, 15);
898 rwlock_init(&GlobalSMBSeslock); 940 spin_lock_init(&cifs_tcp_ses_lock);
899 rwlock_init(&cifs_tcp_ses_lock); 941 spin_lock_init(&cifs_file_list_lock);
900 spin_lock_init(&GlobalMid_Lock); 942 spin_lock_init(&GlobalMid_Lock);
901 943
902 if (cifs_max_pending < 2) { 944 if (cifs_max_pending < 2) {
@@ -909,11 +951,11 @@ init_cifs(void)
909 951
910 rc = cifs_fscache_register(); 952 rc = cifs_fscache_register();
911 if (rc) 953 if (rc)
912 goto out; 954 goto out_clean_proc;
913 955
914 rc = cifs_init_inodecache(); 956 rc = cifs_init_inodecache();
915 if (rc) 957 if (rc)
916 goto out_clean_proc; 958 goto out_unreg_fscache;
917 959
918 rc = cifs_init_mids(); 960 rc = cifs_init_mids();
919 if (rc) 961 if (rc)
@@ -935,19 +977,19 @@ init_cifs(void)
935 return 0; 977 return 0;
936 978
937#ifdef CONFIG_CIFS_UPCALL 979#ifdef CONFIG_CIFS_UPCALL
938 out_unregister_filesystem: 980out_unregister_filesystem:
939 unregister_filesystem(&cifs_fs_type); 981 unregister_filesystem(&cifs_fs_type);
940#endif 982#endif
941 out_destroy_request_bufs: 983out_destroy_request_bufs:
942 cifs_destroy_request_bufs(); 984 cifs_destroy_request_bufs();
943 out_destroy_mids: 985out_destroy_mids:
944 cifs_destroy_mids(); 986 cifs_destroy_mids();
945 out_destroy_inodecache: 987out_destroy_inodecache:
946 cifs_destroy_inodecache(); 988 cifs_destroy_inodecache();
947 out_clean_proc: 989out_unreg_fscache:
948 cifs_proc_clean();
949 cifs_fscache_unregister(); 990 cifs_fscache_unregister();
950 out: 991out_clean_proc:
992 cifs_proc_clean();
951 return rc; 993 return rc;
952} 994}
953 995
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index d82f5fb4761e..f35795a16b42 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -42,10 +42,8 @@ extern const struct address_space_operations cifs_addr_ops;
42extern const struct address_space_operations cifs_addr_ops_smallbuf; 42extern const struct address_space_operations cifs_addr_ops_smallbuf;
43 43
44/* Functions related to super block operations */ 44/* Functions related to super block operations */
45/* extern const struct super_operations cifs_super_ops;*/ 45extern void cifs_sb_active(struct super_block *sb);
46extern void cifs_read_inode(struct inode *); 46extern void cifs_sb_deactive(struct super_block *sb);
47/*extern void cifs_delete_inode(struct inode *);*/ /* BB not needed yet */
48/* extern void cifs_write_inode(struct inode *); */ /* BB not needed yet */
49 47
50/* Functions related to inodes */ 48/* Functions related to inodes */
51extern const struct inode_operations cifs_dir_inode_ops; 49extern const struct inode_operations cifs_dir_inode_ops;
@@ -104,7 +102,7 @@ extern int cifs_readlink(struct dentry *direntry, char __user *buffer,
104extern int cifs_symlink(struct inode *inode, struct dentry *direntry, 102extern int cifs_symlink(struct inode *inode, struct dentry *direntry,
105 const char *symname); 103 const char *symname);
106extern int cifs_removexattr(struct dentry *, const char *); 104extern int cifs_removexattr(struct dentry *, const char *);
107extern int cifs_setxattr(struct dentry *, const char *, const void *, 105extern int cifs_setxattr(struct dentry *, const char *, const void *,
108 size_t, int); 106 size_t, int);
109extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); 107extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
110extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); 108extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
@@ -114,5 +112,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
114extern const struct export_operations cifs_export_ops; 112extern const struct export_operations cifs_export_ops;
115#endif /* EXPERIMENTAL */ 113#endif /* EXPERIMENTAL */
116 114
117#define CIFS_VERSION "1.65" 115#define CIFS_VERSION "1.67"
118#endif /* _CIFSFS_H */ 116#endif /* _CIFSFS_H */
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 0cdfb8c32ac6..3365e77f6f24 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;
@@ -178,12 +179,10 @@ struct TCP_Server_Info {
178 int capabilities; /* allow selective disabling of caps by smb sess */ 179 int capabilities; /* allow selective disabling of caps by smb sess */
179 int timeAdj; /* Adjust for difference in server time zone in sec */ 180 int timeAdj; /* Adjust for difference in server time zone in sec */
180 __u16 CurrentMid; /* multiplex id - rotating counter */ 181 __u16 CurrentMid; /* multiplex id - rotating counter */
181 char cryptKey[CIFS_CRYPTO_KEY_SIZE];
182 /* 16th byte of RFC1001 workstation name is always null */ 182 /* 16th byte of RFC1001 workstation name is always null */
183 char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL]; 183 char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL];
184 __u32 sequence_number; /* needed for CIFS PDU signature */ 184 __u32 sequence_number; /* needed for CIFS PDU signature */
185 struct mac_key mac_signing_key; 185 struct session_key session_key;
186 char ntlmv2_hash[16];
187 unsigned long lstrp; /* when we got last response from this server */ 186 unsigned long lstrp; /* when we got last response from this server */
188 u16 dialect; /* dialect index that server chose */ 187 u16 dialect; /* dialect index that server chose */
189 /* extended security flavors that server supports */ 188 /* extended security flavors that server supports */
@@ -191,6 +190,7 @@ struct TCP_Server_Info {
191 bool sec_mskerberos; /* supports legacy MS Kerberos */ 190 bool sec_mskerberos; /* supports legacy MS Kerberos */
192 bool sec_kerberosu2u; /* supports U2U Kerberos */ 191 bool sec_kerberosu2u; /* supports U2U Kerberos */
193 bool sec_ntlmssp; /* supports NTLMSSP */ 192 bool sec_ntlmssp; /* supports NTLMSSP */
193 bool session_estab; /* mark when very first sess is established */
194#ifdef CONFIG_CIFS_FSCACHE 194#ifdef CONFIG_CIFS_FSCACHE
195 struct fscache_cookie *fscache; /* client index cache cookie */ 195 struct fscache_cookie *fscache; /* client index cache cookie */
196#endif 196#endif
@@ -222,6 +222,11 @@ struct cifsSesInfo {
222 char userName[MAX_USERNAME_SIZE + 1]; 222 char userName[MAX_USERNAME_SIZE + 1];
223 char *domainName; 223 char *domainName;
224 char *password; 224 char *password;
225 char cryptKey[CIFS_CRYPTO_KEY_SIZE];
226 struct session_key auth_key;
227 char ntlmv2_hash[16];
228 unsigned int tilen; /* length of the target info blob */
229 unsigned char *tiblob; /* target info blob in challenge response */
225 bool need_reconnect:1; /* connection reset, uid now invalid */ 230 bool need_reconnect:1; /* connection reset, uid now invalid */
226}; 231};
227/* no more than one of the following three session flags may be set */ 232/* no more than one of the following three session flags may be set */
@@ -308,6 +313,44 @@ struct cifsTconInfo {
308}; 313};
309 314
310/* 315/*
316 * This is a refcounted and timestamped container for a tcon pointer. The
317 * container holds a tcon reference. It is considered safe to free one of
318 * these when the tl_count goes to 0. The tl_time is the time of the last
319 * "get" on the container.
320 */
321struct tcon_link {
322 unsigned long tl_index;
323 unsigned long tl_flags;
324#define TCON_LINK_MASTER 0
325#define TCON_LINK_PENDING 1
326#define TCON_LINK_IN_TREE 2
327 unsigned long tl_time;
328 atomic_t tl_count;
329 struct cifsTconInfo *tl_tcon;
330};
331
332extern struct tcon_link *cifs_sb_tlink(struct cifs_sb_info *cifs_sb);
333
334static inline struct cifsTconInfo *
335tlink_tcon(struct tcon_link *tlink)
336{
337 return tlink->tl_tcon;
338}
339
340extern void cifs_put_tlink(struct tcon_link *tlink);
341
342static inline struct tcon_link *
343cifs_get_tlink(struct tcon_link *tlink)
344{
345 if (tlink && !IS_ERR(tlink))
346 atomic_inc(&tlink->tl_count);
347 return tlink;
348}
349
350/* This function is always expected to succeed */
351extern struct cifsTconInfo *cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb);
352
353/*
311 * This info hangs off the cifsFileInfo structure, pointed to by llist. 354 * This info hangs off the cifsFileInfo structure, pointed to by llist.
312 * This is used to track byte stream locks on the file 355 * This is used to track byte stream locks on the file
313 */ 356 */
@@ -345,12 +388,11 @@ struct cifsFileInfo {
345 __u16 netfid; /* file id from remote */ 388 __u16 netfid; /* file id from remote */
346 /* BB add lock scope info here if needed */ ; 389 /* BB add lock scope info here if needed */ ;
347 /* lock scope id (0 if none) */ 390 /* lock scope id (0 if none) */
348 struct file *pfile; /* needed for writepage */ 391 struct dentry *dentry;
349 struct inode *pInode; /* needed for oplock break */ 392 unsigned int f_flags;
350 struct vfsmount *mnt; 393 struct tcon_link *tlink;
351 struct mutex lock_mutex; 394 struct mutex lock_mutex;
352 struct list_head llist; /* list of byte range locks we have. */ 395 struct list_head llist; /* list of byte range locks we have. */
353 bool closePend:1; /* file is marked to close */
354 bool invalidHandle:1; /* file closed via session abend */ 396 bool invalidHandle:1; /* file closed via session abend */
355 bool oplock_break_cancelled:1; 397 bool oplock_break_cancelled:1;
356 atomic_t count; /* reference count */ 398 atomic_t count; /* reference count */
@@ -365,14 +407,7 @@ static inline void cifsFileInfo_get(struct cifsFileInfo *cifs_file)
365 atomic_inc(&cifs_file->count); 407 atomic_inc(&cifs_file->count);
366} 408}
367 409
368/* Release a reference on the file private data */ 410void cifsFileInfo_put(struct cifsFileInfo *cifs_file);
369static inline void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
370{
371 if (atomic_dec_and_test(&cifs_file->count)) {
372 iput(cifs_file->pInode);
373 kfree(cifs_file);
374 }
375}
376 411
377/* 412/*
378 * One of these for each file inode 413 * One of these for each file inode
@@ -474,16 +509,16 @@ struct oplock_q_entry {
474 509
475/* for pending dnotify requests */ 510/* for pending dnotify requests */
476struct dir_notify_req { 511struct dir_notify_req {
477 struct list_head lhead; 512 struct list_head lhead;
478 __le16 Pid; 513 __le16 Pid;
479 __le16 PidHigh; 514 __le16 PidHigh;
480 __u16 Mid; 515 __u16 Mid;
481 __u16 Tid; 516 __u16 Tid;
482 __u16 Uid; 517 __u16 Uid;
483 __u16 netfid; 518 __u16 netfid;
484 __u32 filter; /* CompletionFilter (for multishot) */ 519 __u32 filter; /* CompletionFilter (for multishot) */
485 int multishot; 520 int multishot;
486 struct file *pfile; 521 struct file *pfile;
487}; 522};
488 523
489struct dfs_info3_param { 524struct dfs_info3_param {
@@ -667,7 +702,7 @@ GLOBAL_EXTERN struct list_head cifs_tcp_ses_list;
667 * the reference counters for the server, smb session, and tcon. Finally, 702 * the reference counters for the server, smb session, and tcon. Finally,
668 * changes to the tcon->tidStatus should be done while holding this lock. 703 * changes to the tcon->tidStatus should be done while holding this lock.
669 */ 704 */
670GLOBAL_EXTERN rwlock_t cifs_tcp_ses_lock; 705GLOBAL_EXTERN spinlock_t cifs_tcp_ses_lock;
671 706
672/* 707/*
673 * This lock protects the cifs_file->llist and cifs_file->flist 708 * This lock protects the cifs_file->llist and cifs_file->flist
@@ -676,7 +711,7 @@ GLOBAL_EXTERN rwlock_t cifs_tcp_ses_lock;
676 * If cifs_tcp_ses_lock and the lock below are both needed to be held, then 711 * If cifs_tcp_ses_lock and the lock below are both needed to be held, then
677 * the cifs_tcp_ses_lock must be grabbed first and released last. 712 * the cifs_tcp_ses_lock must be grabbed first and released last.
678 */ 713 */
679GLOBAL_EXTERN rwlock_t GlobalSMBSeslock; 714GLOBAL_EXTERN spinlock_t cifs_file_list_lock;
680 715
681/* Outstanding dir notify requests */ 716/* Outstanding dir notify requests */
682GLOBAL_EXTERN struct list_head GlobalDnotifyReqList; 717GLOBAL_EXTERN struct list_head GlobalDnotifyReqList;
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..e593c40ba7ba 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);
@@ -105,12 +105,12 @@ extern u64 cifs_UnixTimeToNT(struct timespec);
105extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, 105extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time,
106 int offset); 106 int offset);
107 107
108extern struct cifsFileInfo *cifs_new_fileinfo(struct inode *newinode, 108extern struct cifsFileInfo *cifs_new_fileinfo(__u16 fileHandle,
109 __u16 fileHandle, struct file *file, 109 struct file *file, struct tcon_link *tlink,
110 struct vfsmount *mnt, unsigned int oflags); 110 __u32 oplock);
111extern int cifs_posix_open(char *full_path, struct inode **pinode, 111extern int cifs_posix_open(char *full_path, struct inode **pinode,
112 struct super_block *sb, 112 struct super_block *sb,
113 int mode, int oflags, 113 int mode, unsigned int f_flags,
114 __u32 *poplock, __u16 *pnetfid, int xid); 114 __u32 *poplock, __u16 *pnetfid, int xid);
115void cifs_fill_uniqueid(struct super_block *sb, struct cifs_fattr *fattr); 115void cifs_fill_uniqueid(struct super_block *sb, struct cifs_fattr *fattr);
116extern void cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, 116extern void cifs_unix_basic_to_fattr(struct cifs_fattr *fattr,
@@ -362,12 +362,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 *, 362extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
363 __u32 *); 363 __u32 *);
364extern int cifs_verify_signature(struct smb_hdr *, 364extern int cifs_verify_signature(struct smb_hdr *,
365 const struct mac_key *mac_key, 365 const struct session_key *session_key,
366 __u32 expected_sequence_number); 366 __u32 expected_sequence_number);
367extern int cifs_calculate_mac_key(struct mac_key *key, const char *rn, 367extern int cifs_calculate_session_key(struct session_key *key, const char *rn,
368 const char *pass); 368 const char *pass);
369extern void CalcNTLMv2_response(const struct cifsSesInfo *, char *); 369extern void CalcNTLMv2_response(const struct cifsSesInfo *, char *);
370extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *, 370extern int setup_ntlmv2_rsp(struct cifsSesInfo *, char *,
371 const struct nls_table *); 371 const struct nls_table *);
372#ifdef CONFIG_CIFS_WEAK_PW_HASH 372#ifdef CONFIG_CIFS_WEAK_PW_HASH
373extern void calc_lanman_hash(const char *password, const char *cryptkey, 373extern void calc_lanman_hash(const char *password, const char *cryptkey,
@@ -408,4 +408,8 @@ extern int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
408extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon, 408extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
409 const int netfid, __u64 *pExtAttrBits, __u64 *pMask); 409 const int netfid, __u64 *pExtAttrBits, __u64 *pMask);
410extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb); 410extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb);
411extern bool CIFSCouldBeMFSymlink(const struct cifs_fattr *fattr);
412extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr,
413 const unsigned char *path,
414 struct cifs_sb_info *cifs_sb, int xid);
411#endif /* _CIFSPROTO_H */ 415#endif /* _CIFSPROTO_H */
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 7e83b356cc9e..e98f1f317b15 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -91,13 +91,13 @@ static void mark_open_files_invalid(struct cifsTconInfo *pTcon)
91 struct list_head *tmp1; 91 struct list_head *tmp1;
92 92
93/* list all files open on tree connection and mark them invalid */ 93/* list all files open on tree connection and mark them invalid */
94 write_lock(&GlobalSMBSeslock); 94 spin_lock(&cifs_file_list_lock);
95 list_for_each_safe(tmp, tmp1, &pTcon->openFileList) { 95 list_for_each_safe(tmp, tmp1, &pTcon->openFileList) {
96 open_file = list_entry(tmp, struct cifsFileInfo, tlist); 96 open_file = list_entry(tmp, struct cifsFileInfo, tlist);
97 open_file->invalidHandle = true; 97 open_file->invalidHandle = true;
98 open_file->oplock_break_cancelled = true; 98 open_file->oplock_break_cancelled = true;
99 } 99 }
100 write_unlock(&GlobalSMBSeslock); 100 spin_unlock(&cifs_file_list_lock);
101 /* BB Add call to invalidate_inodes(sb) for all superblocks mounted 101 /* BB Add call to invalidate_inodes(sb) for all superblocks mounted
102 to this tcon */ 102 to this tcon */
103} 103}
@@ -503,7 +503,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
503 503
504 if (rsp->EncryptionKeyLength == 504 if (rsp->EncryptionKeyLength ==
505 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) { 505 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
506 memcpy(server->cryptKey, rsp->EncryptionKey, 506 memcpy(ses->cryptKey, rsp->EncryptionKey,
507 CIFS_CRYPTO_KEY_SIZE); 507 CIFS_CRYPTO_KEY_SIZE);
508 } else if (server->secMode & SECMODE_PW_ENCRYPT) { 508 } else if (server->secMode & SECMODE_PW_ENCRYPT) {
509 rc = -EIO; /* need cryptkey unless plain text */ 509 rc = -EIO; /* need cryptkey unless plain text */
@@ -574,7 +574,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
574 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone); 574 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
575 server->timeAdj *= 60; 575 server->timeAdj *= 60;
576 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { 576 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
577 memcpy(server->cryptKey, pSMBr->u.EncryptionKey, 577 memcpy(ses->cryptKey, pSMBr->u.EncryptionKey,
578 CIFS_CRYPTO_KEY_SIZE); 578 CIFS_CRYPTO_KEY_SIZE);
579 } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) 579 } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC)
580 && (pSMBr->EncryptionKeyLength == 0)) { 580 && (pSMBr->EncryptionKeyLength == 0)) {
@@ -593,9 +593,9 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
593 rc = -EIO; 593 rc = -EIO;
594 goto neg_err_exit; 594 goto neg_err_exit;
595 } 595 }
596 read_lock(&cifs_tcp_ses_lock); 596 spin_lock(&cifs_tcp_ses_lock);
597 if (server->srv_count > 1) { 597 if (server->srv_count > 1) {
598 read_unlock(&cifs_tcp_ses_lock); 598 spin_unlock(&cifs_tcp_ses_lock);
599 if (memcmp(server->server_GUID, 599 if (memcmp(server->server_GUID,
600 pSMBr->u.extended_response. 600 pSMBr->u.extended_response.
601 GUID, 16) != 0) { 601 GUID, 16) != 0) {
@@ -605,7 +605,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
605 16); 605 16);
606 } 606 }
607 } else { 607 } else {
608 read_unlock(&cifs_tcp_ses_lock); 608 spin_unlock(&cifs_tcp_ses_lock);
609 memcpy(server->server_GUID, 609 memcpy(server->server_GUID,
610 pSMBr->u.extended_response.GUID, 16); 610 pSMBr->u.extended_response.GUID, 16);
611 } 611 }
@@ -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..7e73176acb58 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
@@ -143,7 +150,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
143 150
144 /* before reconnecting the tcp session, mark the smb session (uid) 151 /* before reconnecting the tcp session, mark the smb session (uid)
145 and the tid bad so they are not used until reconnected */ 152 and the tid bad so they are not used until reconnected */
146 read_lock(&cifs_tcp_ses_lock); 153 spin_lock(&cifs_tcp_ses_lock);
147 list_for_each(tmp, &server->smb_ses_list) { 154 list_for_each(tmp, &server->smb_ses_list) {
148 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list); 155 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
149 ses->need_reconnect = true; 156 ses->need_reconnect = true;
@@ -153,7 +160,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
153 tcon->need_reconnect = true; 160 tcon->need_reconnect = true;
154 } 161 }
155 } 162 }
156 read_unlock(&cifs_tcp_ses_lock); 163 spin_unlock(&cifs_tcp_ses_lock);
157 /* do not want to be sending data on a socket we are freeing */ 164 /* do not want to be sending data on a socket we are freeing */
158 mutex_lock(&server->srv_mutex); 165 mutex_lock(&server->srv_mutex);
159 if (server->ssocket) { 166 if (server->ssocket) {
@@ -166,6 +173,8 @@ cifs_reconnect(struct TCP_Server_Info *server)
166 sock_release(server->ssocket); 173 sock_release(server->ssocket);
167 server->ssocket = NULL; 174 server->ssocket = NULL;
168 } 175 }
176 server->sequence_number = 0;
177 server->session_estab = false;
169 178
170 spin_lock(&GlobalMid_Lock); 179 spin_lock(&GlobalMid_Lock);
171 list_for_each(tmp, &server->pending_mid_q) { 180 list_for_each(tmp, &server->pending_mid_q) {
@@ -198,7 +207,6 @@ cifs_reconnect(struct TCP_Server_Info *server)
198 spin_lock(&GlobalMid_Lock); 207 spin_lock(&GlobalMid_Lock);
199 if (server->tcpStatus != CifsExiting) 208 if (server->tcpStatus != CifsExiting)
200 server->tcpStatus = CifsGood; 209 server->tcpStatus = CifsGood;
201 server->sequence_number = 0;
202 spin_unlock(&GlobalMid_Lock); 210 spin_unlock(&GlobalMid_Lock);
203 /* atomic_set(&server->inFlight,0);*/ 211 /* atomic_set(&server->inFlight,0);*/
204 wake_up(&server->response_q); 212 wake_up(&server->response_q);
@@ -629,9 +637,9 @@ multi_t2_fnd:
629 } /* end while !EXITING */ 637 } /* end while !EXITING */
630 638
631 /* take it off the list, if it's not already */ 639 /* take it off the list, if it's not already */
632 write_lock(&cifs_tcp_ses_lock); 640 spin_lock(&cifs_tcp_ses_lock);
633 list_del_init(&server->tcp_ses_list); 641 list_del_init(&server->tcp_ses_list);
634 write_unlock(&cifs_tcp_ses_lock); 642 spin_unlock(&cifs_tcp_ses_lock);
635 643
636 spin_lock(&GlobalMid_Lock); 644 spin_lock(&GlobalMid_Lock);
637 server->tcpStatus = CifsExiting; 645 server->tcpStatus = CifsExiting;
@@ -669,7 +677,7 @@ multi_t2_fnd:
669 * BB: we shouldn't have to do any of this. It shouldn't be 677 * BB: we shouldn't have to do any of this. It shouldn't be
670 * possible to exit from the thread with active SMB sessions 678 * possible to exit from the thread with active SMB sessions
671 */ 679 */
672 read_lock(&cifs_tcp_ses_lock); 680 spin_lock(&cifs_tcp_ses_lock);
673 if (list_empty(&server->pending_mid_q)) { 681 if (list_empty(&server->pending_mid_q)) {
674 /* loop through server session structures attached to this and 682 /* loop through server session structures attached to this and
675 mark them dead */ 683 mark them dead */
@@ -679,7 +687,7 @@ multi_t2_fnd:
679 ses->status = CifsExiting; 687 ses->status = CifsExiting;
680 ses->server = NULL; 688 ses->server = NULL;
681 } 689 }
682 read_unlock(&cifs_tcp_ses_lock); 690 spin_unlock(&cifs_tcp_ses_lock);
683 } else { 691 } else {
684 /* although we can not zero the server struct pointer yet, 692 /* although we can not zero the server struct pointer yet,
685 since there are active requests which may depnd on them, 693 since there are active requests which may depnd on them,
@@ -702,7 +710,7 @@ multi_t2_fnd:
702 } 710 }
703 } 711 }
704 spin_unlock(&GlobalMid_Lock); 712 spin_unlock(&GlobalMid_Lock);
705 read_unlock(&cifs_tcp_ses_lock); 713 spin_unlock(&cifs_tcp_ses_lock);
706 /* 1/8th of sec is more than enough time for them to exit */ 714 /* 1/8th of sec is more than enough time for them to exit */
707 msleep(125); 715 msleep(125);
708 } 716 }
@@ -725,12 +733,12 @@ multi_t2_fnd:
725 if a crazy root user tried to kill cifsd 733 if a crazy root user tried to kill cifsd
726 kernel thread explicitly this might happen) */ 734 kernel thread explicitly this might happen) */
727 /* BB: This shouldn't be necessary, see above */ 735 /* BB: This shouldn't be necessary, see above */
728 read_lock(&cifs_tcp_ses_lock); 736 spin_lock(&cifs_tcp_ses_lock);
729 list_for_each(tmp, &server->smb_ses_list) { 737 list_for_each(tmp, &server->smb_ses_list) {
730 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list); 738 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
731 ses->server = NULL; 739 ses->server = NULL;
732 } 740 }
733 read_unlock(&cifs_tcp_ses_lock); 741 spin_unlock(&cifs_tcp_ses_lock);
734 742
735 kfree(server->hostname); 743 kfree(server->hostname);
736 task_to_wake = xchg(&server->tsk, NULL); 744 task_to_wake = xchg(&server->tsk, NULL);
@@ -1046,6 +1054,22 @@ cifs_parse_mount_options(char *options, const char *devname,
1046 "long\n"); 1054 "long\n");
1047 return 1; 1055 return 1;
1048 } 1056 }
1057 } else if (strnicmp(data, "srcaddr", 7) == 0) {
1058 vol->srcaddr.ss_family = AF_UNSPEC;
1059
1060 if (!value || !*value) {
1061 printk(KERN_WARNING "CIFS: srcaddr value"
1062 " not specified.\n");
1063 return 1; /* needs_arg; */
1064 }
1065 i = cifs_convert_address((struct sockaddr *)&vol->srcaddr,
1066 value, strlen(value));
1067 if (i < 0) {
1068 printk(KERN_WARNING "CIFS: Could not parse"
1069 " srcaddr: %s\n",
1070 value);
1071 return 1;
1072 }
1049 } else if (strnicmp(data, "prefixpath", 10) == 0) { 1073 } else if (strnicmp(data, "prefixpath", 10) == 0) {
1050 if (!value || !*value) { 1074 if (!value || !*value) {
1051 printk(KERN_WARNING 1075 printk(KERN_WARNING
@@ -1325,6 +1349,10 @@ cifs_parse_mount_options(char *options, const char *devname,
1325 "/proc/fs/cifs/LookupCacheEnabled to 0\n"); 1349 "/proc/fs/cifs/LookupCacheEnabled to 0\n");
1326 } else if (strnicmp(data, "fsc", 3) == 0) { 1350 } else if (strnicmp(data, "fsc", 3) == 0) {
1327 vol->fsc = true; 1351 vol->fsc = true;
1352 } else if (strnicmp(data, "mfsymlinks", 10) == 0) {
1353 vol->mfsymlinks = true;
1354 } else if (strnicmp(data, "multiuser", 8) == 0) {
1355 vol->multiuser = true;
1328 } else 1356 } else
1329 printk(KERN_WARNING "CIFS: Unknown mount option %s\n", 1357 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
1330 data); 1358 data);
@@ -1356,6 +1384,13 @@ cifs_parse_mount_options(char *options, const char *devname,
1356 return 1; 1384 return 1;
1357 } 1385 }
1358 } 1386 }
1387
1388 if (vol->multiuser && !(vol->secFlg & CIFSSEC_MAY_KRB5)) {
1389 cERROR(1, "Multiuser mounts currently require krb5 "
1390 "authentication!");
1391 return 1;
1392 }
1393
1359 if (vol->UNCip == NULL) 1394 if (vol->UNCip == NULL)
1360 vol->UNCip = &vol->UNC[2]; 1395 vol->UNCip = &vol->UNC[2];
1361 1396
@@ -1374,8 +1409,36 @@ cifs_parse_mount_options(char *options, const char *devname,
1374 return 0; 1409 return 0;
1375} 1410}
1376 1411
1412/** Returns true if srcaddr isn't specified and rhs isn't
1413 * specified, or if srcaddr is specified and
1414 * matches the IP address of the rhs argument.
1415 */
1416static bool
1417srcip_matches(struct sockaddr *srcaddr, struct sockaddr *rhs)
1418{
1419 switch (srcaddr->sa_family) {
1420 case AF_UNSPEC:
1421 return (rhs->sa_family == AF_UNSPEC);
1422 case AF_INET: {
1423 struct sockaddr_in *saddr4 = (struct sockaddr_in *)srcaddr;
1424 struct sockaddr_in *vaddr4 = (struct sockaddr_in *)rhs;
1425 return (saddr4->sin_addr.s_addr == vaddr4->sin_addr.s_addr);
1426 }
1427 case AF_INET6: {
1428 struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)srcaddr;
1429 struct sockaddr_in6 *vaddr6 = (struct sockaddr_in6 *)&rhs;
1430 return ipv6_addr_equal(&saddr6->sin6_addr, &vaddr6->sin6_addr);
1431 }
1432 default:
1433 WARN_ON(1);
1434 return false; /* don't expect to be here */
1435 }
1436}
1437
1438
1377static bool 1439static bool
1378match_address(struct TCP_Server_Info *server, struct sockaddr *addr) 1440match_address(struct TCP_Server_Info *server, struct sockaddr *addr,
1441 struct sockaddr *srcaddr)
1379{ 1442{
1380 struct sockaddr_in *addr4 = (struct sockaddr_in *)addr; 1443 struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
1381 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr; 1444 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
@@ -1402,6 +1465,9 @@ match_address(struct TCP_Server_Info *server, struct sockaddr *addr)
1402 break; 1465 break;
1403 } 1466 }
1404 1467
1468 if (!srcip_matches(srcaddr, (struct sockaddr *)&server->srcaddr))
1469 return false;
1470
1405 return true; 1471 return true;
1406} 1472}
1407 1473
@@ -1458,29 +1524,21 @@ cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol)
1458{ 1524{
1459 struct TCP_Server_Info *server; 1525 struct TCP_Server_Info *server;
1460 1526
1461 write_lock(&cifs_tcp_ses_lock); 1527 spin_lock(&cifs_tcp_ses_lock);
1462 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) { 1528 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
1463 /* 1529 if (!match_address(server, addr,
1464 * the demux thread can exit on its own while still in CifsNew 1530 (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; 1531 continue;
1474 1532
1475 if (!match_security(server, vol)) 1533 if (!match_security(server, vol))
1476 continue; 1534 continue;
1477 1535
1478 ++server->srv_count; 1536 ++server->srv_count;
1479 write_unlock(&cifs_tcp_ses_lock); 1537 spin_unlock(&cifs_tcp_ses_lock);
1480 cFYI(1, "Existing tcp session with server found"); 1538 cFYI(1, "Existing tcp session with server found");
1481 return server; 1539 return server;
1482 } 1540 }
1483 write_unlock(&cifs_tcp_ses_lock); 1541 spin_unlock(&cifs_tcp_ses_lock);
1484 return NULL; 1542 return NULL;
1485} 1543}
1486 1544
@@ -1489,14 +1547,14 @@ cifs_put_tcp_session(struct TCP_Server_Info *server)
1489{ 1547{
1490 struct task_struct *task; 1548 struct task_struct *task;
1491 1549
1492 write_lock(&cifs_tcp_ses_lock); 1550 spin_lock(&cifs_tcp_ses_lock);
1493 if (--server->srv_count > 0) { 1551 if (--server->srv_count > 0) {
1494 write_unlock(&cifs_tcp_ses_lock); 1552 spin_unlock(&cifs_tcp_ses_lock);
1495 return; 1553 return;
1496 } 1554 }
1497 1555
1498 list_del_init(&server->tcp_ses_list); 1556 list_del_init(&server->tcp_ses_list);
1499 write_unlock(&cifs_tcp_ses_lock); 1557 spin_unlock(&cifs_tcp_ses_lock);
1500 1558
1501 spin_lock(&GlobalMid_Lock); 1559 spin_lock(&GlobalMid_Lock);
1502 server->tcpStatus = CifsExiting; 1560 server->tcpStatus = CifsExiting;
@@ -1574,6 +1632,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1574 volume_info->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL); 1632 volume_info->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1575 memcpy(tcp_ses->server_RFC1001_name, 1633 memcpy(tcp_ses->server_RFC1001_name,
1576 volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL); 1634 volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1635 tcp_ses->session_estab = false;
1577 tcp_ses->sequence_number = 0; 1636 tcp_ses->sequence_number = 0;
1578 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list); 1637 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
1579 INIT_LIST_HEAD(&tcp_ses->smb_ses_list); 1638 INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
@@ -1584,6 +1643,8 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1584 * no need to spinlock this init of tcpStatus or srv_count 1643 * no need to spinlock this init of tcpStatus or srv_count
1585 */ 1644 */
1586 tcp_ses->tcpStatus = CifsNew; 1645 tcp_ses->tcpStatus = CifsNew;
1646 memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr,
1647 sizeof(tcp_ses->srcaddr));
1587 ++tcp_ses->srv_count; 1648 ++tcp_ses->srv_count;
1588 1649
1589 if (addr.ss_family == AF_INET6) { 1650 if (addr.ss_family == AF_INET6) {
@@ -1618,9 +1679,9 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1618 } 1679 }
1619 1680
1620 /* thread spawned, put it on the list */ 1681 /* thread spawned, put it on the list */
1621 write_lock(&cifs_tcp_ses_lock); 1682 spin_lock(&cifs_tcp_ses_lock);
1622 list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list); 1683 list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list);
1623 write_unlock(&cifs_tcp_ses_lock); 1684 spin_unlock(&cifs_tcp_ses_lock);
1624 1685
1625 cifs_fscache_get_client_cookie(tcp_ses); 1686 cifs_fscache_get_client_cookie(tcp_ses);
1626 1687
@@ -1642,7 +1703,7 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
1642{ 1703{
1643 struct cifsSesInfo *ses; 1704 struct cifsSesInfo *ses;
1644 1705
1645 write_lock(&cifs_tcp_ses_lock); 1706 spin_lock(&cifs_tcp_ses_lock);
1646 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { 1707 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
1647 switch (server->secType) { 1708 switch (server->secType) {
1648 case Kerberos: 1709 case Kerberos:
@@ -1662,10 +1723,10 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
1662 continue; 1723 continue;
1663 } 1724 }
1664 ++ses->ses_count; 1725 ++ses->ses_count;
1665 write_unlock(&cifs_tcp_ses_lock); 1726 spin_unlock(&cifs_tcp_ses_lock);
1666 return ses; 1727 return ses;
1667 } 1728 }
1668 write_unlock(&cifs_tcp_ses_lock); 1729 spin_unlock(&cifs_tcp_ses_lock);
1669 return NULL; 1730 return NULL;
1670} 1731}
1671 1732
@@ -1676,14 +1737,14 @@ cifs_put_smb_ses(struct cifsSesInfo *ses)
1676 struct TCP_Server_Info *server = ses->server; 1737 struct TCP_Server_Info *server = ses->server;
1677 1738
1678 cFYI(1, "%s: ses_count=%d\n", __func__, ses->ses_count); 1739 cFYI(1, "%s: ses_count=%d\n", __func__, ses->ses_count);
1679 write_lock(&cifs_tcp_ses_lock); 1740 spin_lock(&cifs_tcp_ses_lock);
1680 if (--ses->ses_count > 0) { 1741 if (--ses->ses_count > 0) {
1681 write_unlock(&cifs_tcp_ses_lock); 1742 spin_unlock(&cifs_tcp_ses_lock);
1682 return; 1743 return;
1683 } 1744 }
1684 1745
1685 list_del_init(&ses->smb_ses_list); 1746 list_del_init(&ses->smb_ses_list);
1686 write_unlock(&cifs_tcp_ses_lock); 1747 spin_unlock(&cifs_tcp_ses_lock);
1687 1748
1688 if (ses->status == CifsGood) { 1749 if (ses->status == CifsGood) {
1689 xid = GetXid(); 1750 xid = GetXid();
@@ -1740,6 +1801,8 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
1740 if (ses == NULL) 1801 if (ses == NULL)
1741 goto get_ses_fail; 1802 goto get_ses_fail;
1742 1803
1804 ses->tilen = 0;
1805 ses->tiblob = NULL;
1743 /* new SMB session uses our server ref */ 1806 /* new SMB session uses our server ref */
1744 ses->server = server; 1807 ses->server = server;
1745 if (server->addr.sockAddr6.sin6_family == AF_INET6) 1808 if (server->addr.sockAddr6.sin6_family == AF_INET6)
@@ -1778,9 +1841,9 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
1778 goto get_ses_fail; 1841 goto get_ses_fail;
1779 1842
1780 /* success, put it on the list */ 1843 /* success, put it on the list */
1781 write_lock(&cifs_tcp_ses_lock); 1844 spin_lock(&cifs_tcp_ses_lock);
1782 list_add(&ses->smb_ses_list, &server->smb_ses_list); 1845 list_add(&ses->smb_ses_list, &server->smb_ses_list);
1783 write_unlock(&cifs_tcp_ses_lock); 1846 spin_unlock(&cifs_tcp_ses_lock);
1784 1847
1785 FreeXid(xid); 1848 FreeXid(xid);
1786 return ses; 1849 return ses;
@@ -1797,7 +1860,7 @@ cifs_find_tcon(struct cifsSesInfo *ses, const char *unc)
1797 struct list_head *tmp; 1860 struct list_head *tmp;
1798 struct cifsTconInfo *tcon; 1861 struct cifsTconInfo *tcon;
1799 1862
1800 write_lock(&cifs_tcp_ses_lock); 1863 spin_lock(&cifs_tcp_ses_lock);
1801 list_for_each(tmp, &ses->tcon_list) { 1864 list_for_each(tmp, &ses->tcon_list) {
1802 tcon = list_entry(tmp, struct cifsTconInfo, tcon_list); 1865 tcon = list_entry(tmp, struct cifsTconInfo, tcon_list);
1803 if (tcon->tidStatus == CifsExiting) 1866 if (tcon->tidStatus == CifsExiting)
@@ -1806,10 +1869,10 @@ cifs_find_tcon(struct cifsSesInfo *ses, const char *unc)
1806 continue; 1869 continue;
1807 1870
1808 ++tcon->tc_count; 1871 ++tcon->tc_count;
1809 write_unlock(&cifs_tcp_ses_lock); 1872 spin_unlock(&cifs_tcp_ses_lock);
1810 return tcon; 1873 return tcon;
1811 } 1874 }
1812 write_unlock(&cifs_tcp_ses_lock); 1875 spin_unlock(&cifs_tcp_ses_lock);
1813 return NULL; 1876 return NULL;
1814} 1877}
1815 1878
@@ -1820,14 +1883,14 @@ cifs_put_tcon(struct cifsTconInfo *tcon)
1820 struct cifsSesInfo *ses = tcon->ses; 1883 struct cifsSesInfo *ses = tcon->ses;
1821 1884
1822 cFYI(1, "%s: tc_count=%d\n", __func__, tcon->tc_count); 1885 cFYI(1, "%s: tc_count=%d\n", __func__, tcon->tc_count);
1823 write_lock(&cifs_tcp_ses_lock); 1886 spin_lock(&cifs_tcp_ses_lock);
1824 if (--tcon->tc_count > 0) { 1887 if (--tcon->tc_count > 0) {
1825 write_unlock(&cifs_tcp_ses_lock); 1888 spin_unlock(&cifs_tcp_ses_lock);
1826 return; 1889 return;
1827 } 1890 }
1828 1891
1829 list_del_init(&tcon->tcon_list); 1892 list_del_init(&tcon->tcon_list);
1830 write_unlock(&cifs_tcp_ses_lock); 1893 spin_unlock(&cifs_tcp_ses_lock);
1831 1894
1832 xid = GetXid(); 1895 xid = GetXid();
1833 CIFSSMBTDis(xid, tcon); 1896 CIFSSMBTDis(xid, tcon);
@@ -1900,9 +1963,9 @@ cifs_get_tcon(struct cifsSesInfo *ses, struct smb_vol *volume_info)
1900 tcon->nocase = volume_info->nocase; 1963 tcon->nocase = volume_info->nocase;
1901 tcon->local_lease = volume_info->local_lease; 1964 tcon->local_lease = volume_info->local_lease;
1902 1965
1903 write_lock(&cifs_tcp_ses_lock); 1966 spin_lock(&cifs_tcp_ses_lock);
1904 list_add(&tcon->tcon_list, &ses->tcon_list); 1967 list_add(&tcon->tcon_list, &ses->tcon_list);
1905 write_unlock(&cifs_tcp_ses_lock); 1968 spin_unlock(&cifs_tcp_ses_lock);
1906 1969
1907 cifs_fscache_get_super_cookie(tcon); 1970 cifs_fscache_get_super_cookie(tcon);
1908 1971
@@ -1913,6 +1976,23 @@ out_fail:
1913 return ERR_PTR(rc); 1976 return ERR_PTR(rc);
1914} 1977}
1915 1978
1979void
1980cifs_put_tlink(struct tcon_link *tlink)
1981{
1982 if (!tlink || IS_ERR(tlink))
1983 return;
1984
1985 if (!atomic_dec_and_test(&tlink->tl_count) ||
1986 test_bit(TCON_LINK_IN_TREE, &tlink->tl_flags)) {
1987 tlink->tl_time = jiffies;
1988 return;
1989 }
1990
1991 if (!IS_ERR(tlink_tcon(tlink)))
1992 cifs_put_tcon(tlink_tcon(tlink));
1993 kfree(tlink);
1994 return;
1995}
1916 1996
1917int 1997int
1918get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path, 1998get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
@@ -1997,6 +2077,33 @@ static void rfc1002mangle(char *target, char *source, unsigned int length)
1997 2077
1998} 2078}
1999 2079
2080static int
2081bind_socket(struct TCP_Server_Info *server)
2082{
2083 int rc = 0;
2084 if (server->srcaddr.ss_family != AF_UNSPEC) {
2085 /* Bind to the specified local IP address */
2086 struct socket *socket = server->ssocket;
2087 rc = socket->ops->bind(socket,
2088 (struct sockaddr *) &server->srcaddr,
2089 sizeof(server->srcaddr));
2090 if (rc < 0) {
2091 struct sockaddr_in *saddr4;
2092 struct sockaddr_in6 *saddr6;
2093 saddr4 = (struct sockaddr_in *)&server->srcaddr;
2094 saddr6 = (struct sockaddr_in6 *)&server->srcaddr;
2095 if (saddr6->sin6_family == AF_INET6)
2096 cERROR(1, "cifs: "
2097 "Failed to bind to: %pI6c, error: %d\n",
2098 &saddr6->sin6_addr, rc);
2099 else
2100 cERROR(1, "cifs: "
2101 "Failed to bind to: %pI4, error: %d\n",
2102 &saddr4->sin_addr.s_addr, rc);
2103 }
2104 }
2105 return rc;
2106}
2000 2107
2001static int 2108static int
2002ipv4_connect(struct TCP_Server_Info *server) 2109ipv4_connect(struct TCP_Server_Info *server)
@@ -2022,6 +2129,10 @@ ipv4_connect(struct TCP_Server_Info *server)
2022 cifs_reclassify_socket4(socket); 2129 cifs_reclassify_socket4(socket);
2023 } 2130 }
2024 2131
2132 rc = bind_socket(server);
2133 if (rc < 0)
2134 return rc;
2135
2025 /* user overrode default port */ 2136 /* user overrode default port */
2026 if (server->addr.sockAddr.sin_port) { 2137 if (server->addr.sockAddr.sin_port) {
2027 rc = socket->ops->connect(socket, (struct sockaddr *) 2138 rc = socket->ops->connect(socket, (struct sockaddr *)
@@ -2184,6 +2295,10 @@ ipv6_connect(struct TCP_Server_Info *server)
2184 cifs_reclassify_socket6(socket); 2295 cifs_reclassify_socket6(socket);
2185 } 2296 }
2186 2297
2298 rc = bind_socket(server);
2299 if (rc < 0)
2300 return rc;
2301
2187 /* user overrode default port */ 2302 /* user overrode default port */
2188 if (server->addr.sockAddr6.sin6_port) { 2303 if (server->addr.sockAddr6.sin6_port) {
2189 rc = socket->ops->connect(socket, 2304 rc = socket->ops->connect(socket,
@@ -2383,6 +2498,8 @@ convert_delimiter(char *path, char delim)
2383static void setup_cifs_sb(struct smb_vol *pvolume_info, 2498static void setup_cifs_sb(struct smb_vol *pvolume_info,
2384 struct cifs_sb_info *cifs_sb) 2499 struct cifs_sb_info *cifs_sb)
2385{ 2500{
2501 INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks);
2502
2386 if (pvolume_info->rsize > CIFSMaxBufSize) { 2503 if (pvolume_info->rsize > CIFSMaxBufSize) {
2387 cERROR(1, "rsize %d too large, using MaxBufSize", 2504 cERROR(1, "rsize %d too large, using MaxBufSize",
2388 pvolume_info->rsize); 2505 pvolume_info->rsize);
@@ -2462,10 +2579,21 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
2462 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM; 2579 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
2463 if (pvolume_info->fsc) 2580 if (pvolume_info->fsc)
2464 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE; 2581 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE;
2582 if (pvolume_info->multiuser)
2583 cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_MULTIUSER |
2584 CIFS_MOUNT_NO_PERM);
2465 if (pvolume_info->direct_io) { 2585 if (pvolume_info->direct_io) {
2466 cFYI(1, "mounting share using direct i/o"); 2586 cFYI(1, "mounting share using direct i/o");
2467 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; 2587 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
2468 } 2588 }
2589 if (pvolume_info->mfsymlinks) {
2590 if (pvolume_info->sfu_emul) {
2591 cERROR(1, "mount option mfsymlinks ignored if sfu "
2592 "mount option is used");
2593 } else {
2594 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MF_SYMLINKS;
2595 }
2596 }
2469 2597
2470 if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm)) 2598 if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm))
2471 cERROR(1, "mount option dynperm ignored if cifsacl " 2599 cERROR(1, "mount option dynperm ignored if cifsacl "
@@ -2552,6 +2680,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2552 struct TCP_Server_Info *srvTcp; 2680 struct TCP_Server_Info *srvTcp;
2553 char *full_path; 2681 char *full_path;
2554 char *mount_data = mount_data_global; 2682 char *mount_data = mount_data_global;
2683 struct tcon_link *tlink;
2555#ifdef CONFIG_CIFS_DFS_UPCALL 2684#ifdef CONFIG_CIFS_DFS_UPCALL
2556 struct dfs_info3_param *referrals = NULL; 2685 struct dfs_info3_param *referrals = NULL;
2557 unsigned int num_referrals = 0; 2686 unsigned int num_referrals = 0;
@@ -2563,6 +2692,7 @@ try_mount_again:
2563 pSesInfo = NULL; 2692 pSesInfo = NULL;
2564 srvTcp = NULL; 2693 srvTcp = NULL;
2565 full_path = NULL; 2694 full_path = NULL;
2695 tlink = NULL;
2566 2696
2567 xid = GetXid(); 2697 xid = GetXid();
2568 2698
@@ -2638,8 +2768,6 @@ try_mount_again:
2638 goto remote_path_check; 2768 goto remote_path_check;
2639 } 2769 }
2640 2770
2641 cifs_sb->tcon = tcon;
2642
2643 /* do not care if following two calls succeed - informational */ 2771 /* do not care if following two calls succeed - informational */
2644 if (!tcon->ipc) { 2772 if (!tcon->ipc) {
2645 CIFSSMBQFSDeviceInfo(xid, tcon); 2773 CIFSSMBQFSDeviceInfo(xid, tcon);
@@ -2748,6 +2876,38 @@ remote_path_check:
2748#endif 2876#endif
2749 } 2877 }
2750 2878
2879 if (rc)
2880 goto mount_fail_check;
2881
2882 /* now, hang the tcon off of the superblock */
2883 tlink = kzalloc(sizeof *tlink, GFP_KERNEL);
2884 if (tlink == NULL) {
2885 rc = -ENOMEM;
2886 goto mount_fail_check;
2887 }
2888
2889 tlink->tl_index = pSesInfo->linux_uid;
2890 tlink->tl_tcon = tcon;
2891 tlink->tl_time = jiffies;
2892 set_bit(TCON_LINK_MASTER, &tlink->tl_flags);
2893 set_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
2894
2895 rc = radix_tree_preload(GFP_KERNEL);
2896 if (rc == -ENOMEM) {
2897 kfree(tlink);
2898 goto mount_fail_check;
2899 }
2900
2901 spin_lock(&cifs_sb->tlink_tree_lock);
2902 radix_tree_insert(&cifs_sb->tlink_tree, pSesInfo->linux_uid, tlink);
2903 radix_tree_tag_set(&cifs_sb->tlink_tree, pSesInfo->linux_uid,
2904 CIFS_TLINK_MASTER_TAG);
2905 spin_unlock(&cifs_sb->tlink_tree_lock);
2906 radix_tree_preload_end();
2907
2908 queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks,
2909 TLINK_IDLE_EXPIRE);
2910
2751mount_fail_check: 2911mount_fail_check:
2752 /* on error free sesinfo and tcon struct if needed */ 2912 /* on error free sesinfo and tcon struct if needed */
2753 if (rc) { 2913 if (rc) {
@@ -2825,14 +2985,13 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
2825#ifdef CONFIG_CIFS_WEAK_PW_HASH 2985#ifdef CONFIG_CIFS_WEAK_PW_HASH
2826 if ((global_secflags & CIFSSEC_MAY_LANMAN) && 2986 if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
2827 (ses->server->secType == LANMAN)) 2987 (ses->server->secType == LANMAN))
2828 calc_lanman_hash(tcon->password, ses->server->cryptKey, 2988 calc_lanman_hash(tcon->password, ses->cryptKey,
2829 ses->server->secMode & 2989 ses->server->secMode &
2830 SECMODE_PW_ENCRYPT ? true : false, 2990 SECMODE_PW_ENCRYPT ? true : false,
2831 bcc_ptr); 2991 bcc_ptr);
2832 else 2992 else
2833#endif /* CIFS_WEAK_PW_HASH */ 2993#endif /* CIFS_WEAK_PW_HASH */
2834 SMBNTencrypt(tcon->password, ses->server->cryptKey, 2994 SMBNTencrypt(tcon->password, ses->cryptKey, bcc_ptr);
2835 bcc_ptr);
2836 2995
2837 bcc_ptr += CIFS_SESS_KEY_SIZE; 2996 bcc_ptr += CIFS_SESS_KEY_SIZE;
2838 if (ses->capabilities & CAP_UNICODE) { 2997 if (ses->capabilities & CAP_UNICODE) {
@@ -2934,19 +3093,39 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
2934int 3093int
2935cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) 3094cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
2936{ 3095{
2937 int rc = 0; 3096 int i, ret;
2938 char *tmp; 3097 char *tmp;
3098 struct tcon_link *tlink[8];
3099 unsigned long index = 0;
3100
3101 cancel_delayed_work_sync(&cifs_sb->prune_tlinks);
3102
3103 do {
3104 spin_lock(&cifs_sb->tlink_tree_lock);
3105 ret = radix_tree_gang_lookup(&cifs_sb->tlink_tree,
3106 (void **)tlink, index,
3107 ARRAY_SIZE(tlink));
3108 /* increment index for next pass */
3109 if (ret > 0)
3110 index = tlink[ret - 1]->tl_index + 1;
3111 for (i = 0; i < ret; i++) {
3112 cifs_get_tlink(tlink[i]);
3113 clear_bit(TCON_LINK_IN_TREE, &tlink[i]->tl_flags);
3114 radix_tree_delete(&cifs_sb->tlink_tree,
3115 tlink[i]->tl_index);
3116 }
3117 spin_unlock(&cifs_sb->tlink_tree_lock);
2939 3118
2940 if (cifs_sb->tcon) 3119 for (i = 0; i < ret; i++)
2941 cifs_put_tcon(cifs_sb->tcon); 3120 cifs_put_tlink(tlink[i]);
3121 } while (ret != 0);
2942 3122
2943 cifs_sb->tcon = NULL;
2944 tmp = cifs_sb->prepath; 3123 tmp = cifs_sb->prepath;
2945 cifs_sb->prepathlen = 0; 3124 cifs_sb->prepathlen = 0;
2946 cifs_sb->prepath = NULL; 3125 cifs_sb->prepath = NULL;
2947 kfree(tmp); 3126 kfree(tmp);
2948 3127
2949 return rc; 3128 return 0;
2950} 3129}
2951 3130
2952int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses) 3131int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses)
@@ -2997,6 +3176,15 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
2997 if (rc) { 3176 if (rc) {
2998 cERROR(1, "Send error in SessSetup = %d", rc); 3177 cERROR(1, "Send error in SessSetup = %d", rc);
2999 } else { 3178 } else {
3179 mutex_lock(&ses->server->srv_mutex);
3180 if (!server->session_estab) {
3181 memcpy(&server->session_key.data,
3182 &ses->auth_key.data, ses->auth_key.len);
3183 server->session_key.len = ses->auth_key.len;
3184 ses->server->session_estab = true;
3185 }
3186 mutex_unlock(&server->srv_mutex);
3187
3000 cFYI(1, "CIFS Session Established successfully"); 3188 cFYI(1, "CIFS Session Established successfully");
3001 spin_lock(&GlobalMid_Lock); 3189 spin_lock(&GlobalMid_Lock);
3002 ses->status = CifsGood; 3190 ses->status = CifsGood;
@@ -3007,3 +3195,237 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
3007 return rc; 3195 return rc;
3008} 3196}
3009 3197
3198static struct cifsTconInfo *
3199cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid)
3200{
3201 struct cifsTconInfo *master_tcon = cifs_sb_master_tcon(cifs_sb);
3202 struct cifsSesInfo *ses;
3203 struct cifsTconInfo *tcon = NULL;
3204 struct smb_vol *vol_info;
3205 char username[MAX_USERNAME_SIZE + 1];
3206
3207 vol_info = kzalloc(sizeof(*vol_info), GFP_KERNEL);
3208 if (vol_info == NULL) {
3209 tcon = ERR_PTR(-ENOMEM);
3210 goto out;
3211 }
3212
3213 snprintf(username, MAX_USERNAME_SIZE, "krb50x%x", fsuid);
3214 vol_info->username = username;
3215 vol_info->local_nls = cifs_sb->local_nls;
3216 vol_info->linux_uid = fsuid;
3217 vol_info->cred_uid = fsuid;
3218 vol_info->UNC = master_tcon->treeName;
3219 vol_info->retry = master_tcon->retry;
3220 vol_info->nocase = master_tcon->nocase;
3221 vol_info->local_lease = master_tcon->local_lease;
3222 vol_info->no_linux_ext = !master_tcon->unix_ext;
3223
3224 /* FIXME: allow for other secFlg settings */
3225 vol_info->secFlg = CIFSSEC_MUST_KRB5;
3226
3227 /* get a reference for the same TCP session */
3228 spin_lock(&cifs_tcp_ses_lock);
3229 ++master_tcon->ses->server->srv_count;
3230 spin_unlock(&cifs_tcp_ses_lock);
3231
3232 ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info);
3233 if (IS_ERR(ses)) {
3234 tcon = (struct cifsTconInfo *)ses;
3235 cifs_put_tcp_session(master_tcon->ses->server);
3236 goto out;
3237 }
3238
3239 tcon = cifs_get_tcon(ses, vol_info);
3240 if (IS_ERR(tcon)) {
3241 cifs_put_smb_ses(ses);
3242 goto out;
3243 }
3244
3245 if (ses->capabilities & CAP_UNIX)
3246 reset_cifs_unix_caps(0, tcon, NULL, vol_info);
3247out:
3248 kfree(vol_info);
3249
3250 return tcon;
3251}
3252
3253static struct tcon_link *
3254cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb)
3255{
3256 struct tcon_link *tlink;
3257 unsigned int ret;
3258
3259 spin_lock(&cifs_sb->tlink_tree_lock);
3260 ret = radix_tree_gang_lookup_tag(&cifs_sb->tlink_tree, (void **)&tlink,
3261 0, 1, CIFS_TLINK_MASTER_TAG);
3262 spin_unlock(&cifs_sb->tlink_tree_lock);
3263
3264 /* the master tcon should always be present */
3265 if (ret == 0)
3266 BUG();
3267
3268 return tlink;
3269}
3270
3271struct cifsTconInfo *
3272cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb)
3273{
3274 return tlink_tcon(cifs_sb_master_tlink(cifs_sb));
3275}
3276
3277static int
3278cifs_sb_tcon_pending_wait(void *unused)
3279{
3280 schedule();
3281 return signal_pending(current) ? -ERESTARTSYS : 0;
3282}
3283
3284/*
3285 * Find or construct an appropriate tcon given a cifs_sb and the fsuid of the
3286 * current task.
3287 *
3288 * If the superblock doesn't refer to a multiuser mount, then just return
3289 * the master tcon for the mount.
3290 *
3291 * First, search the radix tree for an existing tcon for this fsuid. If one
3292 * exists, then check to see if it's pending construction. If it is then wait
3293 * for construction to complete. Once it's no longer pending, check to see if
3294 * it failed and either return an error or retry construction, depending on
3295 * the timeout.
3296 *
3297 * If one doesn't exist then insert a new tcon_link struct into the tree and
3298 * try to construct a new one.
3299 */
3300struct tcon_link *
3301cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
3302{
3303 int ret;
3304 unsigned long fsuid = (unsigned long) current_fsuid();
3305 struct tcon_link *tlink, *newtlink;
3306
3307 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
3308 return cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
3309
3310 spin_lock(&cifs_sb->tlink_tree_lock);
3311 tlink = radix_tree_lookup(&cifs_sb->tlink_tree, fsuid);
3312 if (tlink)
3313 cifs_get_tlink(tlink);
3314 spin_unlock(&cifs_sb->tlink_tree_lock);
3315
3316 if (tlink == NULL) {
3317 newtlink = kzalloc(sizeof(*tlink), GFP_KERNEL);
3318 if (newtlink == NULL)
3319 return ERR_PTR(-ENOMEM);
3320 newtlink->tl_index = fsuid;
3321 newtlink->tl_tcon = ERR_PTR(-EACCES);
3322 set_bit(TCON_LINK_PENDING, &newtlink->tl_flags);
3323 set_bit(TCON_LINK_IN_TREE, &newtlink->tl_flags);
3324 cifs_get_tlink(newtlink);
3325
3326 ret = radix_tree_preload(GFP_KERNEL);
3327 if (ret != 0) {
3328 kfree(newtlink);
3329 return ERR_PTR(ret);
3330 }
3331
3332 spin_lock(&cifs_sb->tlink_tree_lock);
3333 /* was one inserted after previous search? */
3334 tlink = radix_tree_lookup(&cifs_sb->tlink_tree, fsuid);
3335 if (tlink) {
3336 cifs_get_tlink(tlink);
3337 spin_unlock(&cifs_sb->tlink_tree_lock);
3338 radix_tree_preload_end();
3339 kfree(newtlink);
3340 goto wait_for_construction;
3341 }
3342 ret = radix_tree_insert(&cifs_sb->tlink_tree, fsuid, newtlink);
3343 spin_unlock(&cifs_sb->tlink_tree_lock);
3344 radix_tree_preload_end();
3345 if (ret) {
3346 kfree(newtlink);
3347 return ERR_PTR(ret);
3348 }
3349 tlink = newtlink;
3350 } else {
3351wait_for_construction:
3352 ret = wait_on_bit(&tlink->tl_flags, TCON_LINK_PENDING,
3353 cifs_sb_tcon_pending_wait,
3354 TASK_INTERRUPTIBLE);
3355 if (ret) {
3356 cifs_put_tlink(tlink);
3357 return ERR_PTR(ret);
3358 }
3359
3360 /* if it's good, return it */
3361 if (!IS_ERR(tlink->tl_tcon))
3362 return tlink;
3363
3364 /* return error if we tried this already recently */
3365 if (time_before(jiffies, tlink->tl_time + TLINK_ERROR_EXPIRE)) {
3366 cifs_put_tlink(tlink);
3367 return ERR_PTR(-EACCES);
3368 }
3369
3370 if (test_and_set_bit(TCON_LINK_PENDING, &tlink->tl_flags))
3371 goto wait_for_construction;
3372 }
3373
3374 tlink->tl_tcon = cifs_construct_tcon(cifs_sb, fsuid);
3375 clear_bit(TCON_LINK_PENDING, &tlink->tl_flags);
3376 wake_up_bit(&tlink->tl_flags, TCON_LINK_PENDING);
3377
3378 if (IS_ERR(tlink->tl_tcon)) {
3379 cifs_put_tlink(tlink);
3380 return ERR_PTR(-EACCES);
3381 }
3382
3383 return tlink;
3384}
3385
3386/*
3387 * periodic workqueue job that scans tcon_tree for a superblock and closes
3388 * out tcons.
3389 */
3390static void
3391cifs_prune_tlinks(struct work_struct *work)
3392{
3393 struct cifs_sb_info *cifs_sb = container_of(work, struct cifs_sb_info,
3394 prune_tlinks.work);
3395 struct tcon_link *tlink[8];
3396 unsigned long now = jiffies;
3397 unsigned long index = 0;
3398 int i, ret;
3399
3400 do {
3401 spin_lock(&cifs_sb->tlink_tree_lock);
3402 ret = radix_tree_gang_lookup(&cifs_sb->tlink_tree,
3403 (void **)tlink, index,
3404 ARRAY_SIZE(tlink));
3405 /* increment index for next pass */
3406 if (ret > 0)
3407 index = tlink[ret - 1]->tl_index + 1;
3408 for (i = 0; i < ret; i++) {
3409 if (test_bit(TCON_LINK_MASTER, &tlink[i]->tl_flags) ||
3410 atomic_read(&tlink[i]->tl_count) != 0 ||
3411 time_after(tlink[i]->tl_time + TLINK_IDLE_EXPIRE,
3412 now)) {
3413 tlink[i] = NULL;
3414 continue;
3415 }
3416 cifs_get_tlink(tlink[i]);
3417 clear_bit(TCON_LINK_IN_TREE, &tlink[i]->tl_flags);
3418 radix_tree_delete(&cifs_sb->tlink_tree,
3419 tlink[i]->tl_index);
3420 }
3421 spin_unlock(&cifs_sb->tlink_tree_lock);
3422
3423 for (i = 0; i < ret; i++) {
3424 if (tlink[i] != NULL)
3425 cifs_put_tlink(tlink[i]);
3426 }
3427 } while (ret != 0);
3428
3429 queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks,
3430 TLINK_IDLE_EXPIRE);
3431}
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index f9ed0751cc12..3840eddbfb7a 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++) {
@@ -130,135 +130,6 @@ cifs_bp_rename_retry:
130 return full_path; 130 return full_path;
131} 131}
132 132
133struct cifsFileInfo *
134cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle,
135 struct file *file, struct vfsmount *mnt, unsigned int oflags)
136{
137 int oplock = 0;
138 struct cifsFileInfo *pCifsFile;
139 struct cifsInodeInfo *pCifsInode;
140 struct cifs_sb_info *cifs_sb = CIFS_SB(mnt->mnt_sb);
141
142 pCifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
143 if (pCifsFile == NULL)
144 return pCifsFile;
145
146 if (oplockEnabled)
147 oplock = REQ_OPLOCK;
148
149 pCifsFile->netfid = fileHandle;
150 pCifsFile->pid = current->tgid;
151 pCifsFile->pInode = igrab(newinode);
152 pCifsFile->mnt = mnt;
153 pCifsFile->pfile = file;
154 pCifsFile->invalidHandle = false;
155 pCifsFile->closePend = false;
156 mutex_init(&pCifsFile->fh_mutex);
157 mutex_init(&pCifsFile->lock_mutex);
158 INIT_LIST_HEAD(&pCifsFile->llist);
159 atomic_set(&pCifsFile->count, 1);
160 INIT_WORK(&pCifsFile->oplock_break, cifs_oplock_break);
161
162 write_lock(&GlobalSMBSeslock);
163 list_add(&pCifsFile->tlist, &cifs_sb->tcon->openFileList);
164 pCifsInode = CIFS_I(newinode);
165 if (pCifsInode) {
166 /* if readable file instance put first in list*/
167 if (oflags & FMODE_READ)
168 list_add(&pCifsFile->flist, &pCifsInode->openFileList);
169 else
170 list_add_tail(&pCifsFile->flist,
171 &pCifsInode->openFileList);
172
173 if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
174 pCifsInode->clientCanCacheAll = true;
175 pCifsInode->clientCanCacheRead = true;
176 cFYI(1, "Exclusive Oplock inode %p", newinode);
177 } else if ((oplock & 0xF) == OPLOCK_READ)
178 pCifsInode->clientCanCacheRead = true;
179 }
180 write_unlock(&GlobalSMBSeslock);
181
182 file->private_data = pCifsFile;
183
184 return pCifsFile;
185}
186
187int cifs_posix_open(char *full_path, struct inode **pinode,
188 struct super_block *sb, int mode, int oflags,
189 __u32 *poplock, __u16 *pnetfid, int xid)
190{
191 int rc;
192 FILE_UNIX_BASIC_INFO *presp_data;
193 __u32 posix_flags = 0;
194 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
195 struct cifs_fattr fattr;
196
197 cFYI(1, "posix open %s", full_path);
198
199 presp_data = kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
200 if (presp_data == NULL)
201 return -ENOMEM;
202
203/* So far cifs posix extensions can only map the following flags.
204 There are other valid fmode oflags such as FMODE_LSEEK, FMODE_PREAD, but
205 so far we do not seem to need them, and we can treat them as local only */
206 if ((oflags & (FMODE_READ | FMODE_WRITE)) ==
207 (FMODE_READ | FMODE_WRITE))
208 posix_flags = SMB_O_RDWR;
209 else if (oflags & FMODE_READ)
210 posix_flags = SMB_O_RDONLY;
211 else if (oflags & FMODE_WRITE)
212 posix_flags = SMB_O_WRONLY;
213 if (oflags & O_CREAT)
214 posix_flags |= SMB_O_CREAT;
215 if (oflags & O_EXCL)
216 posix_flags |= SMB_O_EXCL;
217 if (oflags & O_TRUNC)
218 posix_flags |= SMB_O_TRUNC;
219 /* be safe and imply O_SYNC for O_DSYNC */
220 if (oflags & O_DSYNC)
221 posix_flags |= SMB_O_SYNC;
222 if (oflags & O_DIRECTORY)
223 posix_flags |= SMB_O_DIRECTORY;
224 if (oflags & O_NOFOLLOW)
225 posix_flags |= SMB_O_NOFOLLOW;
226 if (oflags & O_DIRECT)
227 posix_flags |= SMB_O_DIRECT;
228
229 mode &= ~current_umask();
230 rc = CIFSPOSIXCreate(xid, cifs_sb->tcon, posix_flags, mode,
231 pnetfid, presp_data, poplock, full_path,
232 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
233 CIFS_MOUNT_MAP_SPECIAL_CHR);
234 if (rc)
235 goto posix_open_ret;
236
237 if (presp_data->Type == cpu_to_le32(-1))
238 goto posix_open_ret; /* open ok, caller does qpathinfo */
239
240 if (!pinode)
241 goto posix_open_ret; /* caller does not need info */
242
243 cifs_unix_basic_to_fattr(&fattr, presp_data, cifs_sb);
244
245 /* get new inode and set it up */
246 if (*pinode == NULL) {
247 cifs_fill_uniqueid(sb, &fattr);
248 *pinode = cifs_iget(sb, &fattr);
249 if (!*pinode) {
250 rc = -ENOMEM;
251 goto posix_open_ret;
252 }
253 } else {
254 cifs_fattr_to_inode(*pinode, &fattr);
255 }
256
257posix_open_ret:
258 kfree(presp_data);
259 return rc;
260}
261
262static void setup_cifs_dentry(struct cifsTconInfo *tcon, 133static void setup_cifs_dentry(struct cifsTconInfo *tcon,
263 struct dentry *direntry, 134 struct dentry *direntry,
264 struct inode *newinode) 135 struct inode *newinode)
@@ -291,6 +162,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
291 int desiredAccess = GENERIC_READ | GENERIC_WRITE; 162 int desiredAccess = GENERIC_READ | GENERIC_WRITE;
292 __u16 fileHandle; 163 __u16 fileHandle;
293 struct cifs_sb_info *cifs_sb; 164 struct cifs_sb_info *cifs_sb;
165 struct tcon_link *tlink;
294 struct cifsTconInfo *tcon; 166 struct cifsTconInfo *tcon;
295 char *full_path = NULL; 167 char *full_path = NULL;
296 FILE_ALL_INFO *buf = NULL; 168 FILE_ALL_INFO *buf = NULL;
@@ -300,21 +172,26 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
300 xid = GetXid(); 172 xid = GetXid();
301 173
302 cifs_sb = CIFS_SB(inode->i_sb); 174 cifs_sb = CIFS_SB(inode->i_sb);
303 tcon = cifs_sb->tcon; 175 tlink = cifs_sb_tlink(cifs_sb);
304 176 if (IS_ERR(tlink)) {
305 full_path = build_path_from_dentry(direntry); 177 FreeXid(xid);
306 if (full_path == NULL) { 178 return PTR_ERR(tlink);
307 rc = -ENOMEM;
308 goto cifs_create_out;
309 } 179 }
180 tcon = tlink_tcon(tlink);
310 181
311 if (oplockEnabled) 182 if (oplockEnabled)
312 oplock = REQ_OPLOCK; 183 oplock = REQ_OPLOCK;
313 184
314 if (nd && (nd->flags & LOOKUP_OPEN)) 185 if (nd && (nd->flags & LOOKUP_OPEN))
315 oflags = nd->intent.open.flags; 186 oflags = nd->intent.open.file->f_flags;
316 else 187 else
317 oflags = FMODE_READ | SMB_O_CREAT; 188 oflags = O_RDONLY | O_CREAT;
189
190 full_path = build_path_from_dentry(direntry);
191 if (full_path == NULL) {
192 rc = -ENOMEM;
193 goto cifs_create_out;
194 }
318 195
319 if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) && 196 if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) &&
320 (CIFS_UNIX_POSIX_PATH_OPS_CAP & 197 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
@@ -344,9 +221,9 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
344 /* if the file is going to stay open, then we 221 /* if the file is going to stay open, then we
345 need to set the desired access properly */ 222 need to set the desired access properly */
346 desiredAccess = 0; 223 desiredAccess = 0;
347 if (oflags & FMODE_READ) 224 if (OPEN_FMODE(oflags) & FMODE_READ)
348 desiredAccess |= GENERIC_READ; /* is this too little? */ 225 desiredAccess |= GENERIC_READ; /* is this too little? */
349 if (oflags & FMODE_WRITE) 226 if (OPEN_FMODE(oflags) & FMODE_WRITE)
350 desiredAccess |= GENERIC_WRITE; 227 desiredAccess |= GENERIC_WRITE;
351 228
352 if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) 229 if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
@@ -375,7 +252,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
375 if (!tcon->unix_ext && (mode & S_IWUGO) == 0) 252 if (!tcon->unix_ext && (mode & S_IWUGO) == 0)
376 create_options |= CREATE_OPTION_READONLY; 253 create_options |= CREATE_OPTION_READONLY;
377 254
378 if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS) 255 if (tcon->ses->capabilities & CAP_NT_SMBS)
379 rc = CIFSSMBOpen(xid, tcon, full_path, disposition, 256 rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
380 desiredAccess, create_options, 257 desiredAccess, create_options,
381 &fileHandle, &oplock, buf, cifs_sb->local_nls, 258 &fileHandle, &oplock, buf, cifs_sb->local_nls,
@@ -467,8 +344,7 @@ cifs_create_set_dentry:
467 goto cifs_create_out; 344 goto cifs_create_out;
468 } 345 }
469 346
470 pfile_info = cifs_new_fileinfo(newinode, fileHandle, filp, 347 pfile_info = cifs_new_fileinfo(fileHandle, filp, tlink, oplock);
471 nd->path.mnt, oflags);
472 if (pfile_info == NULL) { 348 if (pfile_info == NULL) {
473 fput(filp); 349 fput(filp);
474 CIFSSMBClose(xid, tcon, fileHandle); 350 CIFSSMBClose(xid, tcon, fileHandle);
@@ -481,6 +357,7 @@ cifs_create_set_dentry:
481cifs_create_out: 357cifs_create_out:
482 kfree(buf); 358 kfree(buf);
483 kfree(full_path); 359 kfree(full_path);
360 cifs_put_tlink(tlink);
484 FreeXid(xid); 361 FreeXid(xid);
485 return rc; 362 return rc;
486} 363}
@@ -491,6 +368,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
491 int rc = -EPERM; 368 int rc = -EPERM;
492 int xid; 369 int xid;
493 struct cifs_sb_info *cifs_sb; 370 struct cifs_sb_info *cifs_sb;
371 struct tcon_link *tlink;
494 struct cifsTconInfo *pTcon; 372 struct cifsTconInfo *pTcon;
495 char *full_path = NULL; 373 char *full_path = NULL;
496 struct inode *newinode = NULL; 374 struct inode *newinode = NULL;
@@ -503,10 +381,14 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
503 if (!old_valid_dev(device_number)) 381 if (!old_valid_dev(device_number))
504 return -EINVAL; 382 return -EINVAL;
505 383
506 xid = GetXid();
507
508 cifs_sb = CIFS_SB(inode->i_sb); 384 cifs_sb = CIFS_SB(inode->i_sb);
509 pTcon = cifs_sb->tcon; 385 tlink = cifs_sb_tlink(cifs_sb);
386 if (IS_ERR(tlink))
387 return PTR_ERR(tlink);
388
389 pTcon = tlink_tcon(tlink);
390
391 xid = GetXid();
510 392
511 full_path = build_path_from_dentry(direntry); 393 full_path = build_path_from_dentry(direntry);
512 if (full_path == NULL) { 394 if (full_path == NULL) {
@@ -606,6 +488,7 @@ mknod_out:
606 kfree(full_path); 488 kfree(full_path);
607 kfree(buf); 489 kfree(buf);
608 FreeXid(xid); 490 FreeXid(xid);
491 cifs_put_tlink(tlink);
609 return rc; 492 return rc;
610} 493}
611 494
@@ -619,6 +502,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
619 __u16 fileHandle = 0; 502 __u16 fileHandle = 0;
620 bool posix_open = false; 503 bool posix_open = false;
621 struct cifs_sb_info *cifs_sb; 504 struct cifs_sb_info *cifs_sb;
505 struct tcon_link *tlink;
622 struct cifsTconInfo *pTcon; 506 struct cifsTconInfo *pTcon;
623 struct cifsFileInfo *cfile; 507 struct cifsFileInfo *cfile;
624 struct inode *newInode = NULL; 508 struct inode *newInode = NULL;
@@ -633,7 +517,12 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
633 /* check whether path exists */ 517 /* check whether path exists */
634 518
635 cifs_sb = CIFS_SB(parent_dir_inode->i_sb); 519 cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
636 pTcon = cifs_sb->tcon; 520 tlink = cifs_sb_tlink(cifs_sb);
521 if (IS_ERR(tlink)) {
522 FreeXid(xid);
523 return (struct dentry *)tlink;
524 }
525 pTcon = tlink_tcon(tlink);
637 526
638 /* 527 /*
639 * Don't allow the separator character in a path component. 528 * Don't allow the separator character in a path component.
@@ -644,8 +533,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
644 for (i = 0; i < direntry->d_name.len; i++) 533 for (i = 0; i < direntry->d_name.len; i++)
645 if (direntry->d_name.name[i] == '\\') { 534 if (direntry->d_name.name[i] == '\\') {
646 cFYI(1, "Invalid file name"); 535 cFYI(1, "Invalid file name");
647 FreeXid(xid); 536 rc = -EINVAL;
648 return ERR_PTR(-EINVAL); 537 goto lookup_out;
649 } 538 }
650 } 539 }
651 540
@@ -655,7 +544,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
655 */ 544 */
656 if (nd && (nd->flags & LOOKUP_EXCL)) { 545 if (nd && (nd->flags & LOOKUP_EXCL)) {
657 d_instantiate(direntry, NULL); 546 d_instantiate(direntry, NULL);
658 return NULL; 547 rc = 0;
548 goto lookup_out;
659 } 549 }
660 550
661 /* can not grab the rename sem here since it would 551 /* can not grab the rename sem here since it would
@@ -663,8 +553,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
663 in which we already have the sb rename sem */ 553 in which we already have the sb rename sem */
664 full_path = build_path_from_dentry(direntry); 554 full_path = build_path_from_dentry(direntry);
665 if (full_path == NULL) { 555 if (full_path == NULL) {
666 FreeXid(xid); 556 rc = -ENOMEM;
667 return ERR_PTR(-ENOMEM); 557 goto lookup_out;
668 } 558 }
669 559
670 if (direntry->d_inode != NULL) { 560 if (direntry->d_inode != NULL) {
@@ -687,11 +577,11 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
687 if (pTcon->unix_ext) { 577 if (pTcon->unix_ext) {
688 if (nd && !(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) && 578 if (nd && !(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) &&
689 (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open && 579 (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open &&
690 (nd->intent.open.flags & O_CREAT)) { 580 (nd->intent.open.file->f_flags & O_CREAT)) {
691 rc = cifs_posix_open(full_path, &newInode, 581 rc = cifs_posix_open(full_path, &newInode,
692 parent_dir_inode->i_sb, 582 parent_dir_inode->i_sb,
693 nd->intent.open.create_mode, 583 nd->intent.open.create_mode,
694 nd->intent.open.flags, &oplock, 584 nd->intent.open.file->f_flags, &oplock,
695 &fileHandle, xid); 585 &fileHandle, xid);
696 /* 586 /*
697 * The check below works around a bug in POSIX 587 * The check below works around a bug in POSIX
@@ -727,9 +617,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
727 goto lookup_out; 617 goto lookup_out;
728 } 618 }
729 619
730 cfile = cifs_new_fileinfo(newInode, fileHandle, filp, 620 cfile = cifs_new_fileinfo(fileHandle, filp, tlink,
731 nd->path.mnt, 621 oplock);
732 nd->intent.open.flags);
733 if (cfile == NULL) { 622 if (cfile == NULL) {
734 fput(filp); 623 fput(filp);
735 CIFSSMBClose(xid, pTcon, fileHandle); 624 CIFSSMBClose(xid, pTcon, fileHandle);
@@ -759,6 +648,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
759 648
760lookup_out: 649lookup_out:
761 kfree(full_path); 650 kfree(full_path);
651 cifs_put_tlink(tlink);
762 FreeXid(xid); 652 FreeXid(xid);
763 return ERR_PTR(rc); 653 return ERR_PTR(rc);
764} 654}
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index de748c652d11..8c81e7b14d53 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -60,34 +60,32 @@ static inline int cifs_convert_flags(unsigned int flags)
60 FILE_READ_DATA); 60 FILE_READ_DATA);
61} 61}
62 62
63static inline fmode_t cifs_posix_convert_flags(unsigned int flags) 63static u32 cifs_posix_convert_flags(unsigned int flags)
64{ 64{
65 fmode_t posix_flags = 0; 65 u32 posix_flags = 0;
66 66
67 if ((flags & O_ACCMODE) == O_RDONLY) 67 if ((flags & O_ACCMODE) == O_RDONLY)
68 posix_flags = FMODE_READ; 68 posix_flags = SMB_O_RDONLY;
69 else if ((flags & O_ACCMODE) == O_WRONLY) 69 else if ((flags & O_ACCMODE) == O_WRONLY)
70 posix_flags = FMODE_WRITE; 70 posix_flags = SMB_O_WRONLY;
71 else if ((flags & O_ACCMODE) == O_RDWR) { 71 else if ((flags & O_ACCMODE) == O_RDWR)
72 /* GENERIC_ALL is too much permission to request 72 posix_flags = SMB_O_RDWR;
73 can cause unnecessary access denied on create */ 73
74 /* return GENERIC_ALL; */ 74 if (flags & O_CREAT)
75 posix_flags = FMODE_READ | FMODE_WRITE; 75 posix_flags |= SMB_O_CREAT;
76 } 76 if (flags & O_EXCL)
77 /* can not map O_CREAT or O_EXCL or O_TRUNC flags when 77 posix_flags |= SMB_O_EXCL;
78 reopening a file. They had their effect on the original open */ 78 if (flags & O_TRUNC)
79 if (flags & O_APPEND) 79 posix_flags |= SMB_O_TRUNC;
80 posix_flags |= (fmode_t)O_APPEND; 80 /* be safe and imply O_SYNC for O_DSYNC */
81 if (flags & O_DSYNC) 81 if (flags & O_DSYNC)
82 posix_flags |= (fmode_t)O_DSYNC; 82 posix_flags |= SMB_O_SYNC;
83 if (flags & __O_SYNC)
84 posix_flags |= (fmode_t)__O_SYNC;
85 if (flags & O_DIRECTORY) 83 if (flags & O_DIRECTORY)
86 posix_flags |= (fmode_t)O_DIRECTORY; 84 posix_flags |= SMB_O_DIRECTORY;
87 if (flags & O_NOFOLLOW) 85 if (flags & O_NOFOLLOW)
88 posix_flags |= (fmode_t)O_NOFOLLOW; 86 posix_flags |= SMB_O_NOFOLLOW;
89 if (flags & O_DIRECT) 87 if (flags & O_DIRECT)
90 posix_flags |= (fmode_t)O_DIRECT; 88 posix_flags |= SMB_O_DIRECT;
91 89
92 return posix_flags; 90 return posix_flags;
93} 91}
@@ -106,66 +104,8 @@ static inline int cifs_get_disposition(unsigned int flags)
106 return FILE_OPEN; 104 return FILE_OPEN;
107} 105}
108 106
109/* all arguments to this function must be checked for validity in caller */
110static inline int
111cifs_posix_open_inode_helper(struct inode *inode, struct file *file,
112 struct cifsInodeInfo *pCifsInode, __u32 oplock,
113 u16 netfid)
114{
115
116 write_lock(&GlobalSMBSeslock);
117
118 pCifsInode = CIFS_I(file->f_path.dentry->d_inode);
119 if (pCifsInode == NULL) {
120 write_unlock(&GlobalSMBSeslock);
121 return -EINVAL;
122 }
123
124 if (pCifsInode->clientCanCacheRead) {
125 /* we have the inode open somewhere else
126 no need to discard cache data */
127 goto psx_client_can_cache;
128 }
129
130 /* BB FIXME need to fix this check to move it earlier into posix_open
131 BB fIX following section BB FIXME */
132
133 /* if not oplocked, invalidate inode pages if mtime or file
134 size changed */
135/* temp = cifs_NTtimeToUnix(le64_to_cpu(buf->LastWriteTime));
136 if (timespec_equal(&file->f_path.dentry->d_inode->i_mtime, &temp) &&
137 (file->f_path.dentry->d_inode->i_size ==
138 (loff_t)le64_to_cpu(buf->EndOfFile))) {
139 cFYI(1, "inode unchanged on server");
140 } else {
141 if (file->f_path.dentry->d_inode->i_mapping) {
142 rc = filemap_write_and_wait(file->f_path.dentry->d_inode->i_mapping);
143 if (rc != 0)
144 CIFS_I(file->f_path.dentry->d_inode)->write_behind_rc = rc;
145 }
146 cFYI(1, "invalidating remote inode since open detected it "
147 "changed");
148 invalidate_remote_inode(file->f_path.dentry->d_inode);
149 } */
150
151psx_client_can_cache:
152 if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
153 pCifsInode->clientCanCacheAll = true;
154 pCifsInode->clientCanCacheRead = true;
155 cFYI(1, "Exclusive Oplock granted on inode %p",
156 file->f_path.dentry->d_inode);
157 } else if ((oplock & 0xF) == OPLOCK_READ)
158 pCifsInode->clientCanCacheRead = true;
159
160 /* will have to change the unlock if we reenable the
161 filemap_fdatawrite (which does not seem necessary */
162 write_unlock(&GlobalSMBSeslock);
163 return 0;
164}
165
166/* all arguments to this function must be checked for validity in caller */
167static inline int cifs_open_inode_helper(struct inode *inode, 107static inline int cifs_open_inode_helper(struct inode *inode,
168 struct cifsTconInfo *pTcon, int *oplock, FILE_ALL_INFO *buf, 108 struct cifsTconInfo *pTcon, __u32 oplock, FILE_ALL_INFO *buf,
169 char *full_path, int xid) 109 char *full_path, int xid)
170{ 110{
171 struct cifsInodeInfo *pCifsInode = CIFS_I(inode); 111 struct cifsInodeInfo *pCifsInode = CIFS_I(inode);
@@ -207,16 +147,175 @@ client_can_cache:
207 rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb, 147 rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb,
208 xid, NULL); 148 xid, NULL);
209 149
210 if ((*oplock & 0xF) == OPLOCK_EXCLUSIVE) { 150 if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
211 pCifsInode->clientCanCacheAll = true; 151 pCifsInode->clientCanCacheAll = true;
212 pCifsInode->clientCanCacheRead = true; 152 pCifsInode->clientCanCacheRead = true;
213 cFYI(1, "Exclusive Oplock granted on inode %p", inode); 153 cFYI(1, "Exclusive Oplock granted on inode %p", inode);
214 } else if ((*oplock & 0xF) == OPLOCK_READ) 154 } else if ((oplock & 0xF) == OPLOCK_READ)
215 pCifsInode->clientCanCacheRead = true; 155 pCifsInode->clientCanCacheRead = true;
216 156
217 return rc; 157 return rc;
218} 158}
219 159
160int cifs_posix_open(char *full_path, struct inode **pinode,
161 struct super_block *sb, int mode, unsigned int f_flags,
162 __u32 *poplock, __u16 *pnetfid, int xid)
163{
164 int rc;
165 FILE_UNIX_BASIC_INFO *presp_data;
166 __u32 posix_flags = 0;
167 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
168 struct cifs_fattr fattr;
169 struct tcon_link *tlink;
170 struct cifsTconInfo *tcon;
171
172 cFYI(1, "posix open %s", full_path);
173
174 presp_data = kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
175 if (presp_data == NULL)
176 return -ENOMEM;
177
178 tlink = cifs_sb_tlink(cifs_sb);
179 if (IS_ERR(tlink)) {
180 rc = PTR_ERR(tlink);
181 goto posix_open_ret;
182 }
183
184 tcon = tlink_tcon(tlink);
185 mode &= ~current_umask();
186
187 posix_flags = cifs_posix_convert_flags(f_flags);
188 rc = CIFSPOSIXCreate(xid, tcon, posix_flags, mode, pnetfid, presp_data,
189 poplock, full_path, cifs_sb->local_nls,
190 cifs_sb->mnt_cifs_flags &
191 CIFS_MOUNT_MAP_SPECIAL_CHR);
192 cifs_put_tlink(tlink);
193
194 if (rc)
195 goto posix_open_ret;
196
197 if (presp_data->Type == cpu_to_le32(-1))
198 goto posix_open_ret; /* open ok, caller does qpathinfo */
199
200 if (!pinode)
201 goto posix_open_ret; /* caller does not need info */
202
203 cifs_unix_basic_to_fattr(&fattr, presp_data, cifs_sb);
204
205 /* get new inode and set it up */
206 if (*pinode == NULL) {
207 cifs_fill_uniqueid(sb, &fattr);
208 *pinode = cifs_iget(sb, &fattr);
209 if (!*pinode) {
210 rc = -ENOMEM;
211 goto posix_open_ret;
212 }
213 } else {
214 cifs_fattr_to_inode(*pinode, &fattr);
215 }
216
217posix_open_ret:
218 kfree(presp_data);
219 return rc;
220}
221
222struct cifsFileInfo *
223cifs_new_fileinfo(__u16 fileHandle, struct file *file,
224 struct tcon_link *tlink, __u32 oplock)
225{
226 struct dentry *dentry = file->f_path.dentry;
227 struct inode *inode = dentry->d_inode;
228 struct cifsInodeInfo *pCifsInode = CIFS_I(inode);
229 struct cifsFileInfo *pCifsFile;
230
231 pCifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
232 if (pCifsFile == NULL)
233 return pCifsFile;
234
235 pCifsFile->netfid = fileHandle;
236 pCifsFile->pid = current->tgid;
237 pCifsFile->uid = current_fsuid();
238 pCifsFile->dentry = dget(dentry);
239 pCifsFile->f_flags = file->f_flags;
240 pCifsFile->invalidHandle = false;
241 pCifsFile->tlink = cifs_get_tlink(tlink);
242 mutex_init(&pCifsFile->fh_mutex);
243 mutex_init(&pCifsFile->lock_mutex);
244 INIT_LIST_HEAD(&pCifsFile->llist);
245 atomic_set(&pCifsFile->count, 1);
246 INIT_WORK(&pCifsFile->oplock_break, cifs_oplock_break);
247
248 spin_lock(&cifs_file_list_lock);
249 list_add(&pCifsFile->tlist, &(tlink_tcon(tlink)->openFileList));
250 /* if readable file instance put first in list*/
251 if (file->f_mode & FMODE_READ)
252 list_add(&pCifsFile->flist, &pCifsInode->openFileList);
253 else
254 list_add_tail(&pCifsFile->flist, &pCifsInode->openFileList);
255 spin_unlock(&cifs_file_list_lock);
256
257 if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
258 pCifsInode->clientCanCacheAll = true;
259 pCifsInode->clientCanCacheRead = true;
260 cFYI(1, "Exclusive Oplock inode %p", inode);
261 } else if ((oplock & 0xF) == OPLOCK_READ)
262 pCifsInode->clientCanCacheRead = true;
263
264 file->private_data = pCifsFile;
265 return pCifsFile;
266}
267
268/*
269 * Release a reference on the file private data. This may involve closing
270 * the filehandle out on the server.
271 */
272void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
273{
274 struct cifsTconInfo *tcon = tlink_tcon(cifs_file->tlink);
275 struct cifsInodeInfo *cifsi = CIFS_I(cifs_file->dentry->d_inode);
276 struct cifsLockInfo *li, *tmp;
277
278 spin_lock(&cifs_file_list_lock);
279 if (!atomic_dec_and_test(&cifs_file->count)) {
280 spin_unlock(&cifs_file_list_lock);
281 return;
282 }
283
284 /* remove it from the lists */
285 list_del(&cifs_file->flist);
286 list_del(&cifs_file->tlist);
287
288 if (list_empty(&cifsi->openFileList)) {
289 cFYI(1, "closing last open instance for inode %p",
290 cifs_file->dentry->d_inode);
291 cifsi->clientCanCacheRead = false;
292 cifsi->clientCanCacheAll = false;
293 }
294 spin_unlock(&cifs_file_list_lock);
295
296 if (!tcon->need_reconnect && !cifs_file->invalidHandle) {
297 int xid, rc;
298
299 xid = GetXid();
300 rc = CIFSSMBClose(xid, tcon, cifs_file->netfid);
301 FreeXid(xid);
302 }
303
304 /* Delete any outstanding lock records. We'll lose them when the file
305 * is closed anyway.
306 */
307 mutex_lock(&cifs_file->lock_mutex);
308 list_for_each_entry_safe(li, tmp, &cifs_file->llist, llist) {
309 list_del(&li->llist);
310 kfree(li);
311 }
312 mutex_unlock(&cifs_file->lock_mutex);
313
314 cifs_put_tlink(cifs_file->tlink);
315 dput(cifs_file->dentry);
316 kfree(cifs_file);
317}
318
220int cifs_open(struct inode *inode, struct file *file) 319int cifs_open(struct inode *inode, struct file *file)
221{ 320{
222 int rc = -EACCES; 321 int rc = -EACCES;
@@ -224,6 +323,7 @@ int cifs_open(struct inode *inode, struct file *file)
224 __u32 oplock; 323 __u32 oplock;
225 struct cifs_sb_info *cifs_sb; 324 struct cifs_sb_info *cifs_sb;
226 struct cifsTconInfo *tcon; 325 struct cifsTconInfo *tcon;
326 struct tcon_link *tlink;
227 struct cifsFileInfo *pCifsFile = NULL; 327 struct cifsFileInfo *pCifsFile = NULL;
228 struct cifsInodeInfo *pCifsInode; 328 struct cifsInodeInfo *pCifsInode;
229 char *full_path = NULL; 329 char *full_path = NULL;
@@ -235,7 +335,12 @@ int cifs_open(struct inode *inode, struct file *file)
235 xid = GetXid(); 335 xid = GetXid();
236 336
237 cifs_sb = CIFS_SB(inode->i_sb); 337 cifs_sb = CIFS_SB(inode->i_sb);
238 tcon = cifs_sb->tcon; 338 tlink = cifs_sb_tlink(cifs_sb);
339 if (IS_ERR(tlink)) {
340 FreeXid(xid);
341 return PTR_ERR(tlink);
342 }
343 tcon = tlink_tcon(tlink);
239 344
240 pCifsInode = CIFS_I(file->f_path.dentry->d_inode); 345 pCifsInode = CIFS_I(file->f_path.dentry->d_inode);
241 346
@@ -257,27 +362,15 @@ int cifs_open(struct inode *inode, struct file *file)
257 (tcon->ses->capabilities & CAP_UNIX) && 362 (tcon->ses->capabilities & CAP_UNIX) &&
258 (CIFS_UNIX_POSIX_PATH_OPS_CAP & 363 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
259 le64_to_cpu(tcon->fsUnixInfo.Capability))) { 364 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
260 int oflags = (int) cifs_posix_convert_flags(file->f_flags);
261 oflags |= SMB_O_CREAT;
262 /* can not refresh inode info since size could be stale */ 365 /* can not refresh inode info since size could be stale */
263 rc = cifs_posix_open(full_path, &inode, inode->i_sb, 366 rc = cifs_posix_open(full_path, &inode, inode->i_sb,
264 cifs_sb->mnt_file_mode /* ignored */, 367 cifs_sb->mnt_file_mode /* ignored */,
265 oflags, &oplock, &netfid, xid); 368 file->f_flags, &oplock, &netfid, xid);
266 if (rc == 0) { 369 if (rc == 0) {
267 cFYI(1, "posix open succeeded"); 370 cFYI(1, "posix open succeeded");
268 /* no need for special case handling of setting mode
269 on read only files needed here */
270 371
271 rc = cifs_posix_open_inode_helper(inode, file, 372 pCifsFile = cifs_new_fileinfo(netfid, file, tlink,
272 pCifsInode, oplock, netfid); 373 oplock);
273 if (rc != 0) {
274 CIFSSMBClose(xid, tcon, netfid);
275 goto out;
276 }
277
278 pCifsFile = cifs_new_fileinfo(inode, netfid, file,
279 file->f_path.mnt,
280 oflags);
281 if (pCifsFile == NULL) { 374 if (pCifsFile == NULL) {
282 CIFSSMBClose(xid, tcon, netfid); 375 CIFSSMBClose(xid, tcon, netfid);
283 rc = -ENOMEM; 376 rc = -ENOMEM;
@@ -345,7 +438,7 @@ int cifs_open(struct inode *inode, struct file *file)
345 goto out; 438 goto out;
346 } 439 }
347 440
348 if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS) 441 if (tcon->ses->capabilities & CAP_NT_SMBS)
349 rc = CIFSSMBOpen(xid, tcon, full_path, disposition, 442 rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
350 desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf, 443 desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf,
351 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags 444 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
@@ -365,12 +458,11 @@ int cifs_open(struct inode *inode, struct file *file)
365 goto out; 458 goto out;
366 } 459 }
367 460
368 rc = cifs_open_inode_helper(inode, tcon, &oplock, buf, full_path, xid); 461 rc = cifs_open_inode_helper(inode, tcon, oplock, buf, full_path, xid);
369 if (rc != 0) 462 if (rc != 0)
370 goto out; 463 goto out;
371 464
372 pCifsFile = cifs_new_fileinfo(inode, netfid, file, file->f_path.mnt, 465 pCifsFile = cifs_new_fileinfo(netfid, file, tlink, oplock);
373 file->f_flags);
374 if (pCifsFile == NULL) { 466 if (pCifsFile == NULL) {
375 rc = -ENOMEM; 467 rc = -ENOMEM;
376 goto out; 468 goto out;
@@ -402,6 +494,7 @@ out:
402 kfree(buf); 494 kfree(buf);
403 kfree(full_path); 495 kfree(full_path);
404 FreeXid(xid); 496 FreeXid(xid);
497 cifs_put_tlink(tlink);
405 return rc; 498 return rc;
406} 499}
407 500
@@ -416,14 +509,13 @@ static int cifs_relock_file(struct cifsFileInfo *cifsFile)
416 return rc; 509 return rc;
417} 510}
418 511
419static int cifs_reopen_file(struct file *file, bool can_flush) 512static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
420{ 513{
421 int rc = -EACCES; 514 int rc = -EACCES;
422 int xid; 515 int xid;
423 __u32 oplock; 516 __u32 oplock;
424 struct cifs_sb_info *cifs_sb; 517 struct cifs_sb_info *cifs_sb;
425 struct cifsTconInfo *tcon; 518 struct cifsTconInfo *tcon;
426 struct cifsFileInfo *pCifsFile;
427 struct cifsInodeInfo *pCifsInode; 519 struct cifsInodeInfo *pCifsInode;
428 struct inode *inode; 520 struct inode *inode;
429 char *full_path = NULL; 521 char *full_path = NULL;
@@ -431,11 +523,6 @@ static int cifs_reopen_file(struct file *file, bool can_flush)
431 int disposition = FILE_OPEN; 523 int disposition = FILE_OPEN;
432 __u16 netfid; 524 __u16 netfid;
433 525
434 if (file->private_data)
435 pCifsFile = file->private_data;
436 else
437 return -EBADF;
438
439 xid = GetXid(); 526 xid = GetXid();
440 mutex_lock(&pCifsFile->fh_mutex); 527 mutex_lock(&pCifsFile->fh_mutex);
441 if (!pCifsFile->invalidHandle) { 528 if (!pCifsFile->invalidHandle) {
@@ -445,39 +532,24 @@ static int cifs_reopen_file(struct file *file, bool can_flush)
445 return rc; 532 return rc;
446 } 533 }
447 534
448 if (file->f_path.dentry == NULL) { 535 inode = pCifsFile->dentry->d_inode;
449 cERROR(1, "no valid name if dentry freed");
450 dump_stack();
451 rc = -EBADF;
452 goto reopen_error_exit;
453 }
454
455 inode = file->f_path.dentry->d_inode;
456 if (inode == NULL) {
457 cERROR(1, "inode not valid");
458 dump_stack();
459 rc = -EBADF;
460 goto reopen_error_exit;
461 }
462
463 cifs_sb = CIFS_SB(inode->i_sb); 536 cifs_sb = CIFS_SB(inode->i_sb);
464 tcon = cifs_sb->tcon; 537 tcon = tlink_tcon(pCifsFile->tlink);
465 538
466/* can not grab rename sem here because various ops, including 539/* can not grab rename sem here because various ops, including
467 those that already have the rename sem can end up causing writepage 540 those that already have the rename sem can end up causing writepage
468 to get called and if the server was down that means we end up here, 541 to get called and if the server was down that means we end up here,
469 and we can never tell if the caller already has the rename_sem */ 542 and we can never tell if the caller already has the rename_sem */
470 full_path = build_path_from_dentry(file->f_path.dentry); 543 full_path = build_path_from_dentry(pCifsFile->dentry);
471 if (full_path == NULL) { 544 if (full_path == NULL) {
472 rc = -ENOMEM; 545 rc = -ENOMEM;
473reopen_error_exit:
474 mutex_unlock(&pCifsFile->fh_mutex); 546 mutex_unlock(&pCifsFile->fh_mutex);
475 FreeXid(xid); 547 FreeXid(xid);
476 return rc; 548 return rc;
477 } 549 }
478 550
479 cFYI(1, "inode = 0x%p file flags 0x%x for %s", 551 cFYI(1, "inode = 0x%p file flags 0x%x for %s",
480 inode, file->f_flags, full_path); 552 inode, pCifsFile->f_flags, full_path);
481 553
482 if (oplockEnabled) 554 if (oplockEnabled)
483 oplock = REQ_OPLOCK; 555 oplock = REQ_OPLOCK;
@@ -487,8 +559,14 @@ reopen_error_exit:
487 if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) && 559 if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) &&
488 (CIFS_UNIX_POSIX_PATH_OPS_CAP & 560 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
489 le64_to_cpu(tcon->fsUnixInfo.Capability))) { 561 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
490 int oflags = (int) cifs_posix_convert_flags(file->f_flags); 562
491 /* can not refresh inode info since size could be stale */ 563 /*
564 * O_CREAT, O_EXCL and O_TRUNC already had their effect on the
565 * original open. Must mask them off for a reopen.
566 */
567 unsigned int oflags = pCifsFile->f_flags &
568 ~(O_CREAT | O_EXCL | O_TRUNC);
569
492 rc = cifs_posix_open(full_path, NULL, inode->i_sb, 570 rc = cifs_posix_open(full_path, NULL, inode->i_sb,
493 cifs_sb->mnt_file_mode /* ignored */, 571 cifs_sb->mnt_file_mode /* ignored */,
494 oflags, &oplock, &netfid, xid); 572 oflags, &oplock, &netfid, xid);
@@ -500,7 +578,7 @@ reopen_error_exit:
500 in the reconnect path it is important to retry hard */ 578 in the reconnect path it is important to retry hard */
501 } 579 }
502 580
503 desiredAccess = cifs_convert_flags(file->f_flags); 581 desiredAccess = cifs_convert_flags(pCifsFile->f_flags);
504 582
505 /* Can not refresh inode by passing in file_info buf to be returned 583 /* Can not refresh inode by passing in file_info buf to be returned
506 by SMBOpen and then calling get_inode_info with returned buf 584 by SMBOpen and then calling get_inode_info with returned buf
@@ -516,49 +594,50 @@ reopen_error_exit:
516 mutex_unlock(&pCifsFile->fh_mutex); 594 mutex_unlock(&pCifsFile->fh_mutex);
517 cFYI(1, "cifs_open returned 0x%x", rc); 595 cFYI(1, "cifs_open returned 0x%x", rc);
518 cFYI(1, "oplock: %d", oplock); 596 cFYI(1, "oplock: %d", oplock);
519 } else { 597 goto reopen_error_exit;
598 }
599
520reopen_success: 600reopen_success:
521 pCifsFile->netfid = netfid; 601 pCifsFile->netfid = netfid;
522 pCifsFile->invalidHandle = false; 602 pCifsFile->invalidHandle = false;
523 mutex_unlock(&pCifsFile->fh_mutex); 603 mutex_unlock(&pCifsFile->fh_mutex);
524 pCifsInode = CIFS_I(inode); 604 pCifsInode = CIFS_I(inode);
525 if (pCifsInode) { 605
526 if (can_flush) { 606 if (can_flush) {
527 rc = filemap_write_and_wait(inode->i_mapping); 607 rc = filemap_write_and_wait(inode->i_mapping);
528 if (rc != 0) 608 if (rc != 0)
529 CIFS_I(inode)->write_behind_rc = rc; 609 CIFS_I(inode)->write_behind_rc = rc;
530 /* temporarily disable caching while we 610
531 go to server to get inode info */ 611 pCifsInode->clientCanCacheAll = false;
532 pCifsInode->clientCanCacheAll = false; 612 pCifsInode->clientCanCacheRead = false;
533 pCifsInode->clientCanCacheRead = false; 613 if (tcon->unix_ext)
534 if (tcon->unix_ext) 614 rc = cifs_get_inode_info_unix(&inode,
535 rc = cifs_get_inode_info_unix(&inode, 615 full_path, inode->i_sb, xid);
536 full_path, inode->i_sb, xid); 616 else
537 else 617 rc = cifs_get_inode_info(&inode,
538 rc = cifs_get_inode_info(&inode, 618 full_path, NULL, inode->i_sb,
539 full_path, NULL, inode->i_sb, 619 xid, NULL);
540 xid, NULL); 620 } /* else we are writing out data to server already
541 } /* else we are writing out data to server already 621 and could deadlock if we tried to flush data, and
542 and could deadlock if we tried to flush data, and 622 since we do not know if we have data that would
543 since we do not know if we have data that would 623 invalidate the current end of file on the server
544 invalidate the current end of file on the server 624 we can not go to the server to get the new inod
545 we can not go to the server to get the new inod 625 info */
546 info */ 626 if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
547 if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { 627 pCifsInode->clientCanCacheAll = true;
548 pCifsInode->clientCanCacheAll = true; 628 pCifsInode->clientCanCacheRead = true;
549 pCifsInode->clientCanCacheRead = true; 629 cFYI(1, "Exclusive Oplock granted on inode %p",
550 cFYI(1, "Exclusive Oplock granted on inode %p", 630 pCifsFile->dentry->d_inode);
551 file->f_path.dentry->d_inode); 631 } else if ((oplock & 0xF) == OPLOCK_READ) {
552 } else if ((oplock & 0xF) == OPLOCK_READ) { 632 pCifsInode->clientCanCacheRead = true;
553 pCifsInode->clientCanCacheRead = true; 633 pCifsInode->clientCanCacheAll = false;
554 pCifsInode->clientCanCacheAll = false; 634 } else {
555 } else { 635 pCifsInode->clientCanCacheRead = false;
556 pCifsInode->clientCanCacheRead = false; 636 pCifsInode->clientCanCacheAll = false;
557 pCifsInode->clientCanCacheAll = false;
558 }
559 cifs_relock_file(pCifsFile);
560 }
561 } 637 }
638 cifs_relock_file(pCifsFile);
639
640reopen_error_exit:
562 kfree(full_path); 641 kfree(full_path);
563 FreeXid(xid); 642 FreeXid(xid);
564 return rc; 643 return rc;
@@ -566,79 +645,11 @@ reopen_success:
566 645
567int cifs_close(struct inode *inode, struct file *file) 646int cifs_close(struct inode *inode, struct file *file)
568{ 647{
569 int rc = 0; 648 cifsFileInfo_put(file->private_data);
570 int xid, timeout; 649 file->private_data = NULL;
571 struct cifs_sb_info *cifs_sb;
572 struct cifsTconInfo *pTcon;
573 struct cifsFileInfo *pSMBFile = file->private_data;
574 650
575 xid = GetXid(); 651 /* return code from the ->release op is always ignored */
576 652 return 0;
577 cifs_sb = CIFS_SB(inode->i_sb);
578 pTcon = cifs_sb->tcon;
579 if (pSMBFile) {
580 struct cifsLockInfo *li, *tmp;
581 write_lock(&GlobalSMBSeslock);
582 pSMBFile->closePend = true;
583 if (pTcon) {
584 /* no sense reconnecting to close a file that is
585 already closed */
586 if (!pTcon->need_reconnect) {
587 write_unlock(&GlobalSMBSeslock);
588 timeout = 2;
589 while ((atomic_read(&pSMBFile->count) != 1)
590 && (timeout <= 2048)) {
591 /* Give write a better chance to get to
592 server ahead of the close. We do not
593 want to add a wait_q here as it would
594 increase the memory utilization as
595 the struct would be in each open file,
596 but this should give enough time to
597 clear the socket */
598 cFYI(DBG2, "close delay, write pending");
599 msleep(timeout);
600 timeout *= 4;
601 }
602 if (!pTcon->need_reconnect &&
603 !pSMBFile->invalidHandle)
604 rc = CIFSSMBClose(xid, pTcon,
605 pSMBFile->netfid);
606 } else
607 write_unlock(&GlobalSMBSeslock);
608 } else
609 write_unlock(&GlobalSMBSeslock);
610
611 /* Delete any outstanding lock records.
612 We'll lose them when the file is closed anyway. */
613 mutex_lock(&pSMBFile->lock_mutex);
614 list_for_each_entry_safe(li, tmp, &pSMBFile->llist, llist) {
615 list_del(&li->llist);
616 kfree(li);
617 }
618 mutex_unlock(&pSMBFile->lock_mutex);
619
620 write_lock(&GlobalSMBSeslock);
621 list_del(&pSMBFile->flist);
622 list_del(&pSMBFile->tlist);
623 write_unlock(&GlobalSMBSeslock);
624 cifsFileInfo_put(file->private_data);
625 file->private_data = NULL;
626 } else
627 rc = -EBADF;
628
629 read_lock(&GlobalSMBSeslock);
630 if (list_empty(&(CIFS_I(inode)->openFileList))) {
631 cFYI(1, "closing last open instance for inode %p", inode);
632 /* if the file is not open we do not know if we can cache info
633 on this inode, much less write behind and read ahead */
634 CIFS_I(inode)->clientCanCacheRead = false;
635 CIFS_I(inode)->clientCanCacheAll = false;
636 }
637 read_unlock(&GlobalSMBSeslock);
638 if ((rc == 0) && CIFS_I(inode)->write_behind_rc)
639 rc = CIFS_I(inode)->write_behind_rc;
640 FreeXid(xid);
641 return rc;
642} 653}
643 654
644int cifs_closedir(struct inode *inode, struct file *file) 655int cifs_closedir(struct inode *inode, struct file *file)
@@ -653,25 +664,21 @@ int cifs_closedir(struct inode *inode, struct file *file)
653 xid = GetXid(); 664 xid = GetXid();
654 665
655 if (pCFileStruct) { 666 if (pCFileStruct) {
656 struct cifsTconInfo *pTcon; 667 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 668
662 cFYI(1, "Freeing private data in close dir"); 669 cFYI(1, "Freeing private data in close dir");
663 write_lock(&GlobalSMBSeslock); 670 spin_lock(&cifs_file_list_lock);
664 if (!pCFileStruct->srch_inf.endOfSearch && 671 if (!pCFileStruct->srch_inf.endOfSearch &&
665 !pCFileStruct->invalidHandle) { 672 !pCFileStruct->invalidHandle) {
666 pCFileStruct->invalidHandle = true; 673 pCFileStruct->invalidHandle = true;
667 write_unlock(&GlobalSMBSeslock); 674 spin_unlock(&cifs_file_list_lock);
668 rc = CIFSFindClose(xid, pTcon, pCFileStruct->netfid); 675 rc = CIFSFindClose(xid, pTcon, pCFileStruct->netfid);
669 cFYI(1, "Closing uncompleted readdir with rc %d", 676 cFYI(1, "Closing uncompleted readdir with rc %d",
670 rc); 677 rc);
671 /* not much we can do if it fails anyway, ignore rc */ 678 /* not much we can do if it fails anyway, ignore rc */
672 rc = 0; 679 rc = 0;
673 } else 680 } else
674 write_unlock(&GlobalSMBSeslock); 681 spin_unlock(&cifs_file_list_lock);
675 ptmp = pCFileStruct->srch_inf.ntwrk_buf_start; 682 ptmp = pCFileStruct->srch_inf.ntwrk_buf_start;
676 if (ptmp) { 683 if (ptmp) {
677 cFYI(1, "closedir free smb buf in srch struct"); 684 cFYI(1, "closedir free smb buf in srch struct");
@@ -681,6 +688,7 @@ int cifs_closedir(struct inode *inode, struct file *file)
681 else 688 else
682 cifs_buf_release(ptmp); 689 cifs_buf_release(ptmp);
683 } 690 }
691 cifs_put_tlink(pCFileStruct->tlink);
684 kfree(file->private_data); 692 kfree(file->private_data);
685 file->private_data = NULL; 693 file->private_data = NULL;
686 } 694 }
@@ -767,7 +775,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
767 cFYI(1, "Unknown type of lock"); 775 cFYI(1, "Unknown type of lock");
768 776
769 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 777 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
770 tcon = cifs_sb->tcon; 778 tcon = tlink_tcon(((struct cifsFileInfo *)file->private_data)->tlink);
771 779
772 if (file->private_data == NULL) { 780 if (file->private_data == NULL) {
773 rc = -EBADF; 781 rc = -EBADF;
@@ -960,14 +968,14 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
960 968
961 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 969 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
962 970
963 pTcon = cifs_sb->tcon;
964
965 /* cFYI(1, " write %d bytes to offset %lld of %s", write_size, 971 /* cFYI(1, " write %d bytes to offset %lld of %s", write_size,
966 *poffset, file->f_path.dentry->d_name.name); */ 972 *poffset, file->f_path.dentry->d_name.name); */
967 973
968 if (file->private_data == NULL) 974 if (file->private_data == NULL)
969 return -EBADF; 975 return -EBADF;
976
970 open_file = file->private_data; 977 open_file = file->private_data;
978 pTcon = tlink_tcon(open_file->tlink);
971 979
972 rc = generic_write_checks(file, poffset, &write_size, 0); 980 rc = generic_write_checks(file, poffset, &write_size, 0);
973 if (rc) 981 if (rc)
@@ -988,19 +996,12 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
988 we blocked so return what we managed to write */ 996 we blocked so return what we managed to write */
989 return total_written; 997 return total_written;
990 } 998 }
991 if (open_file->closePend) {
992 FreeXid(xid);
993 if (total_written)
994 return total_written;
995 else
996 return -EBADF;
997 }
998 if (open_file->invalidHandle) { 999 if (open_file->invalidHandle) {
999 /* we could deadlock if we called 1000 /* we could deadlock if we called
1000 filemap_fdatawait from here so tell 1001 filemap_fdatawait from here so tell
1001 reopen_file not to flush data to server 1002 reopen_file not to flush data to server
1002 now */ 1003 now */
1003 rc = cifs_reopen_file(file, false); 1004 rc = cifs_reopen_file(open_file, false);
1004 if (rc != 0) 1005 if (rc != 0)
1005 break; 1006 break;
1006 } 1007 }
@@ -1048,8 +1049,9 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
1048 return total_written; 1049 return total_written;
1049} 1050}
1050 1051
1051static ssize_t cifs_write(struct file *file, const char *write_data, 1052static ssize_t cifs_write(struct cifsFileInfo *open_file,
1052 size_t write_size, loff_t *poffset) 1053 const char *write_data, size_t write_size,
1054 loff_t *poffset)
1053{ 1055{
1054 int rc = 0; 1056 int rc = 0;
1055 unsigned int bytes_written = 0; 1057 unsigned int bytes_written = 0;
@@ -1057,19 +1059,15 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
1057 struct cifs_sb_info *cifs_sb; 1059 struct cifs_sb_info *cifs_sb;
1058 struct cifsTconInfo *pTcon; 1060 struct cifsTconInfo *pTcon;
1059 int xid, long_op; 1061 int xid, long_op;
1060 struct cifsFileInfo *open_file; 1062 struct dentry *dentry = open_file->dentry;
1061 struct cifsInodeInfo *cifsi = CIFS_I(file->f_path.dentry->d_inode); 1063 struct cifsInodeInfo *cifsi = CIFS_I(dentry->d_inode);
1062 1064
1063 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 1065 cifs_sb = CIFS_SB(dentry->d_sb);
1064
1065 pTcon = cifs_sb->tcon;
1066 1066
1067 cFYI(1, "write %zd bytes to offset %lld of %s", write_size, 1067 cFYI(1, "write %zd bytes to offset %lld of %s", write_size,
1068 *poffset, file->f_path.dentry->d_name.name); 1068 *poffset, dentry->d_name.name);
1069 1069
1070 if (file->private_data == NULL) 1070 pTcon = tlink_tcon(open_file->tlink);
1071 return -EBADF;
1072 open_file = file->private_data;
1073 1071
1074 xid = GetXid(); 1072 xid = GetXid();
1075 1073
@@ -1078,28 +1076,12 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
1078 total_written += bytes_written) { 1076 total_written += bytes_written) {
1079 rc = -EAGAIN; 1077 rc = -EAGAIN;
1080 while (rc == -EAGAIN) { 1078 while (rc == -EAGAIN) {
1081 if (file->private_data == NULL) {
1082 /* file has been closed on us */
1083 FreeXid(xid);
1084 /* if we have gotten here we have written some data
1085 and blocked, and the file has been freed on us
1086 while we blocked so return what we managed to
1087 write */
1088 return total_written;
1089 }
1090 if (open_file->closePend) {
1091 FreeXid(xid);
1092 if (total_written)
1093 return total_written;
1094 else
1095 return -EBADF;
1096 }
1097 if (open_file->invalidHandle) { 1079 if (open_file->invalidHandle) {
1098 /* we could deadlock if we called 1080 /* we could deadlock if we called
1099 filemap_fdatawait from here so tell 1081 filemap_fdatawait from here so tell
1100 reopen_file not to flush data to 1082 reopen_file not to flush data to
1101 server now */ 1083 server now */
1102 rc = cifs_reopen_file(file, false); 1084 rc = cifs_reopen_file(open_file, false);
1103 if (rc != 0) 1085 if (rc != 0)
1104 break; 1086 break;
1105 } 1087 }
@@ -1146,43 +1128,41 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
1146 1128
1147 cifs_stats_bytes_written(pTcon, total_written); 1129 cifs_stats_bytes_written(pTcon, total_written);
1148 1130
1149 /* since the write may have blocked check these pointers again */ 1131 if (total_written > 0) {
1150 if ((file->f_path.dentry) && (file->f_path.dentry->d_inode)) { 1132 spin_lock(&dentry->d_inode->i_lock);
1151/*BB We could make this contingent on superblock ATIME flag too */ 1133 if (*poffset > dentry->d_inode->i_size)
1152/* file->f_path.dentry->d_inode->i_ctime = 1134 i_size_write(dentry->d_inode, *poffset);
1153 file->f_path.dentry->d_inode->i_mtime = CURRENT_TIME;*/ 1135 spin_unlock(&dentry->d_inode->i_lock);
1154 if (total_written > 0) {
1155 spin_lock(&file->f_path.dentry->d_inode->i_lock);
1156 if (*poffset > file->f_path.dentry->d_inode->i_size)
1157 i_size_write(file->f_path.dentry->d_inode,
1158 *poffset);
1159 spin_unlock(&file->f_path.dentry->d_inode->i_lock);
1160 }
1161 mark_inode_dirty_sync(file->f_path.dentry->d_inode);
1162 } 1136 }
1137 mark_inode_dirty_sync(dentry->d_inode);
1163 FreeXid(xid); 1138 FreeXid(xid);
1164 return total_written; 1139 return total_written;
1165} 1140}
1166 1141
1167#ifdef CONFIG_CIFS_EXPERIMENTAL 1142#ifdef CONFIG_CIFS_EXPERIMENTAL
1168struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode) 1143struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
1144 bool fsuid_only)
1169{ 1145{
1170 struct cifsFileInfo *open_file = NULL; 1146 struct cifsFileInfo *open_file = NULL;
1147 struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb);
1148
1149 /* only filter by fsuid on multiuser mounts */
1150 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
1151 fsuid_only = false;
1171 1152
1172 read_lock(&GlobalSMBSeslock); 1153 spin_lock(&cifs_file_list_lock);
1173 /* we could simply get the first_list_entry since write-only entries 1154 /* we could simply get the first_list_entry since write-only entries
1174 are always at the end of the list but since the first entry might 1155 are always at the end of the list but since the first entry might
1175 have a close pending, we go through the whole list */ 1156 have a close pending, we go through the whole list */
1176 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { 1157 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
1177 if (open_file->closePend) 1158 if (fsuid_only && open_file->uid != current_fsuid())
1178 continue; 1159 continue;
1179 if (open_file->pfile && ((open_file->pfile->f_flags & O_RDWR) || 1160 if (OPEN_FMODE(open_file->f_flags) & FMODE_READ) {
1180 (open_file->pfile->f_flags & O_RDONLY))) {
1181 if (!open_file->invalidHandle) { 1161 if (!open_file->invalidHandle) {
1182 /* found a good file */ 1162 /* found a good file */
1183 /* lock it so it will not be closed on us */ 1163 /* lock it so it will not be closed on us */
1184 cifsFileInfo_get(open_file); 1164 cifsFileInfo_get(open_file);
1185 read_unlock(&GlobalSMBSeslock); 1165 spin_unlock(&cifs_file_list_lock);
1186 return open_file; 1166 return open_file;
1187 } /* else might as well continue, and look for 1167 } /* else might as well continue, and look for
1188 another, or simply have the caller reopen it 1168 another, or simply have the caller reopen it
@@ -1190,14 +1170,16 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode)
1190 } else /* write only file */ 1170 } else /* write only file */
1191 break; /* write only files are last so must be done */ 1171 break; /* write only files are last so must be done */
1192 } 1172 }
1193 read_unlock(&GlobalSMBSeslock); 1173 spin_unlock(&cifs_file_list_lock);
1194 return NULL; 1174 return NULL;
1195} 1175}
1196#endif 1176#endif
1197 1177
1198struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) 1178struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,
1179 bool fsuid_only)
1199{ 1180{
1200 struct cifsFileInfo *open_file; 1181 struct cifsFileInfo *open_file;
1182 struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb);
1201 bool any_available = false; 1183 bool any_available = false;
1202 int rc; 1184 int rc;
1203 1185
@@ -1211,53 +1193,39 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
1211 return NULL; 1193 return NULL;
1212 } 1194 }
1213 1195
1214 read_lock(&GlobalSMBSeslock); 1196 /* only filter by fsuid on multiuser mounts */
1197 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
1198 fsuid_only = false;
1199
1200 spin_lock(&cifs_file_list_lock);
1215refind_writable: 1201refind_writable:
1216 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { 1202 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
1217 if (open_file->closePend || 1203 if (!any_available && open_file->pid != current->tgid)
1218 (!any_available && open_file->pid != current->tgid))
1219 continue; 1204 continue;
1220 1205 if (fsuid_only && open_file->uid != current_fsuid())
1221 if (open_file->pfile && 1206 continue;
1222 ((open_file->pfile->f_flags & O_RDWR) || 1207 if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) {
1223 (open_file->pfile->f_flags & O_WRONLY))) {
1224 cifsFileInfo_get(open_file); 1208 cifsFileInfo_get(open_file);
1225 1209
1226 if (!open_file->invalidHandle) { 1210 if (!open_file->invalidHandle) {
1227 /* found a good writable file */ 1211 /* found a good writable file */
1228 read_unlock(&GlobalSMBSeslock); 1212 spin_unlock(&cifs_file_list_lock);
1229 return open_file; 1213 return open_file;
1230 } 1214 }
1231 1215
1232 read_unlock(&GlobalSMBSeslock); 1216 spin_unlock(&cifs_file_list_lock);
1217
1233 /* Had to unlock since following call can block */ 1218 /* Had to unlock since following call can block */
1234 rc = cifs_reopen_file(open_file->pfile, false); 1219 rc = cifs_reopen_file(open_file, false);
1235 if (!rc) { 1220 if (!rc)
1236 if (!open_file->closePend) 1221 return open_file;
1237 return open_file;
1238 else { /* start over in case this was deleted */
1239 /* since the list could be modified */
1240 read_lock(&GlobalSMBSeslock);
1241 cifsFileInfo_put(open_file);
1242 goto refind_writable;
1243 }
1244 }
1245 1222
1246 /* if it fails, try another handle if possible - 1223 /* if it fails, try another handle if possible */
1247 (we can not do this if closePending since
1248 loop could be modified - in which case we
1249 have to start at the beginning of the list
1250 again. Note that it would be bad
1251 to hold up writepages here (rather than
1252 in caller) with continuous retries */
1253 cFYI(1, "wp failed on reopen file"); 1224 cFYI(1, "wp failed on reopen file");
1254 read_lock(&GlobalSMBSeslock);
1255 /* can not use this handle, no write
1256 pending on this one after all */
1257 cifsFileInfo_put(open_file); 1225 cifsFileInfo_put(open_file);
1258 1226
1259 if (open_file->closePend) /* list could have changed */ 1227 spin_lock(&cifs_file_list_lock);
1260 goto refind_writable; 1228
1261 /* else we simply continue to the next entry. Thus 1229 /* else we simply continue to the next entry. Thus
1262 we do not loop on reopen errors. If we 1230 we do not loop on reopen errors. If we
1263 can not reopen the file, for example if we 1231 can not reopen the file, for example if we
@@ -1272,7 +1240,7 @@ refind_writable:
1272 any_available = true; 1240 any_available = true;
1273 goto refind_writable; 1241 goto refind_writable;
1274 } 1242 }
1275 read_unlock(&GlobalSMBSeslock); 1243 spin_unlock(&cifs_file_list_lock);
1276 return NULL; 1244 return NULL;
1277} 1245}
1278 1246
@@ -1284,7 +1252,6 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
1284 int rc = -EFAULT; 1252 int rc = -EFAULT;
1285 int bytes_written = 0; 1253 int bytes_written = 0;
1286 struct cifs_sb_info *cifs_sb; 1254 struct cifs_sb_info *cifs_sb;
1287 struct cifsTconInfo *pTcon;
1288 struct inode *inode; 1255 struct inode *inode;
1289 struct cifsFileInfo *open_file; 1256 struct cifsFileInfo *open_file;
1290 1257
@@ -1293,7 +1260,6 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
1293 1260
1294 inode = page->mapping->host; 1261 inode = page->mapping->host;
1295 cifs_sb = CIFS_SB(inode->i_sb); 1262 cifs_sb = CIFS_SB(inode->i_sb);
1296 pTcon = cifs_sb->tcon;
1297 1263
1298 offset += (loff_t)from; 1264 offset += (loff_t)from;
1299 write_data = kmap(page); 1265 write_data = kmap(page);
@@ -1314,10 +1280,10 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
1314 if (mapping->host->i_size - offset < (loff_t)to) 1280 if (mapping->host->i_size - offset < (loff_t)to)
1315 to = (unsigned)(mapping->host->i_size - offset); 1281 to = (unsigned)(mapping->host->i_size - offset);
1316 1282
1317 open_file = find_writable_file(CIFS_I(mapping->host)); 1283 open_file = find_writable_file(CIFS_I(mapping->host), false);
1318 if (open_file) { 1284 if (open_file) {
1319 bytes_written = cifs_write(open_file->pfile, write_data, 1285 bytes_written = cifs_write(open_file, write_data,
1320 to-from, &offset); 1286 to - from, &offset);
1321 cifsFileInfo_put(open_file); 1287 cifsFileInfo_put(open_file);
1322 /* Does mm or vfs already set times? */ 1288 /* Does mm or vfs already set times? */
1323 inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb); 1289 inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb);
@@ -1352,6 +1318,7 @@ static int cifs_writepages(struct address_space *mapping,
1352 int nr_pages; 1318 int nr_pages;
1353 __u64 offset = 0; 1319 __u64 offset = 0;
1354 struct cifsFileInfo *open_file; 1320 struct cifsFileInfo *open_file;
1321 struct cifsTconInfo *tcon;
1355 struct cifsInodeInfo *cifsi = CIFS_I(mapping->host); 1322 struct cifsInodeInfo *cifsi = CIFS_I(mapping->host);
1356 struct page *page; 1323 struct page *page;
1357 struct pagevec pvec; 1324 struct pagevec pvec;
@@ -1359,6 +1326,15 @@ static int cifs_writepages(struct address_space *mapping,
1359 int scanned = 0; 1326 int scanned = 0;
1360 int xid, long_op; 1327 int xid, long_op;
1361 1328
1329 /*
1330 * BB: Is this meaningful for a non-block-device file system?
1331 * If it is, we should test it again after we do I/O
1332 */
1333 if (wbc->nonblocking && bdi_write_congested(bdi)) {
1334 wbc->encountered_congestion = 1;
1335 return 0;
1336 }
1337
1362 cifs_sb = CIFS_SB(mapping->host->i_sb); 1338 cifs_sb = CIFS_SB(mapping->host->i_sb);
1363 1339
1364 /* 1340 /*
@@ -1368,27 +1344,29 @@ static int cifs_writepages(struct address_space *mapping,
1368 if (cifs_sb->wsize < PAGE_CACHE_SIZE) 1344 if (cifs_sb->wsize < PAGE_CACHE_SIZE)
1369 return generic_writepages(mapping, wbc); 1345 return generic_writepages(mapping, wbc);
1370 1346
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); 1347 iov = kmalloc(32 * sizeof(struct kvec), GFP_KERNEL);
1378 if (iov == NULL) 1348 if (iov == NULL)
1379 return generic_writepages(mapping, wbc); 1349 return generic_writepages(mapping, wbc);
1380 1350
1381
1382 /* 1351 /*
1383 * BB: Is this meaningful for a non-block-device file system? 1352 * 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 1353 * but it'll at least handle the return. Maybe it should be
1354 * a BUG() instead?
1385 */ 1355 */
1386 if (wbc->nonblocking && bdi_write_congested(bdi)) { 1356 open_file = find_writable_file(CIFS_I(mapping->host), false);
1387 wbc->encountered_congestion = 1; 1357 if (!open_file) {
1388 kfree(iov); 1358 kfree(iov);
1389 return 0; 1359 return generic_writepages(mapping, wbc);
1390 } 1360 }
1391 1361
1362 tcon = tlink_tcon(open_file->tlink);
1363 if (!experimEnabled && tcon->ses->server->secMode &
1364 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
1365 cifsFileInfo_put(open_file);
1366 return generic_writepages(mapping, wbc);
1367 }
1368 cifsFileInfo_put(open_file);
1369
1392 xid = GetXid(); 1370 xid = GetXid();
1393 1371
1394 pagevec_init(&pvec, 0); 1372 pagevec_init(&pvec, 0);
@@ -1492,38 +1470,34 @@ retry:
1492 break; 1470 break;
1493 } 1471 }
1494 if (n_iov) { 1472 if (n_iov) {
1495 /* Search for a writable handle every time we call 1473 open_file = find_writable_file(CIFS_I(mapping->host),
1496 * CIFSSMBWrite2. We can't rely on the last handle 1474 false);
1497 * we used to still be valid
1498 */
1499 open_file = find_writable_file(CIFS_I(mapping->host));
1500 if (!open_file) { 1475 if (!open_file) {
1501 cERROR(1, "No writable handles for inode"); 1476 cERROR(1, "No writable handles for inode");
1502 rc = -EBADF; 1477 rc = -EBADF;
1503 } else { 1478 } else {
1504 long_op = cifs_write_timeout(cifsi, offset); 1479 long_op = cifs_write_timeout(cifsi, offset);
1505 rc = CIFSSMBWrite2(xid, cifs_sb->tcon, 1480 rc = CIFSSMBWrite2(xid, tcon, open_file->netfid,
1506 open_file->netfid,
1507 bytes_to_write, offset, 1481 bytes_to_write, offset,
1508 &bytes_written, iov, n_iov, 1482 &bytes_written, iov, n_iov,
1509 long_op); 1483 long_op);
1510 cifsFileInfo_put(open_file); 1484 cifsFileInfo_put(open_file);
1511 cifs_update_eof(cifsi, offset, bytes_written); 1485 cifs_update_eof(cifsi, offset, bytes_written);
1486 }
1512 1487
1513 if (rc || bytes_written < bytes_to_write) { 1488 if (rc || bytes_written < bytes_to_write) {
1514 cERROR(1, "Write2 ret %d, wrote %d", 1489 cERROR(1, "Write2 ret %d, wrote %d",
1515 rc, bytes_written); 1490 rc, bytes_written);
1516 /* BB what if continued retry is 1491 /* BB what if continued retry is
1517 requested via mount flags? */ 1492 requested via mount flags? */
1518 if (rc == -ENOSPC) 1493 if (rc == -ENOSPC)
1519 set_bit(AS_ENOSPC, &mapping->flags); 1494 set_bit(AS_ENOSPC, &mapping->flags);
1520 else 1495 else
1521 set_bit(AS_EIO, &mapping->flags); 1496 set_bit(AS_EIO, &mapping->flags);
1522 } else { 1497 } else {
1523 cifs_stats_bytes_written(cifs_sb->tcon, 1498 cifs_stats_bytes_written(tcon, bytes_written);
1524 bytes_written);
1525 }
1526 } 1499 }
1500
1527 for (i = 0; i < n_iov; i++) { 1501 for (i = 0; i < n_iov; i++) {
1528 page = pvec.pages[first + i]; 1502 page = pvec.pages[first + i];
1529 /* Should we also set page error on 1503 /* Should we also set page error on
@@ -1624,7 +1598,8 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
1624 /* BB check if anything else missing out of ppw 1598 /* BB check if anything else missing out of ppw
1625 such as updating last write time */ 1599 such as updating last write time */
1626 page_data = kmap(page); 1600 page_data = kmap(page);
1627 rc = cifs_write(file, page_data + offset, copied, &pos); 1601 rc = cifs_write(file->private_data, page_data + offset,
1602 copied, &pos);
1628 /* if (rc < 0) should we set writebehind rc? */ 1603 /* if (rc < 0) should we set writebehind rc? */
1629 kunmap(page); 1604 kunmap(page);
1630 1605
@@ -1665,7 +1640,7 @@ int cifs_fsync(struct file *file, int datasync)
1665 if (rc == 0) { 1640 if (rc == 0) {
1666 rc = CIFS_I(inode)->write_behind_rc; 1641 rc = CIFS_I(inode)->write_behind_rc;
1667 CIFS_I(inode)->write_behind_rc = 0; 1642 CIFS_I(inode)->write_behind_rc = 0;
1668 tcon = CIFS_SB(inode->i_sb)->tcon; 1643 tcon = tlink_tcon(smbfile->tlink);
1669 if (!rc && tcon && smbfile && 1644 if (!rc && tcon && smbfile &&
1670 !(CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) 1645 !(CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC))
1671 rc = CIFSSMBFlush(xid, tcon, smbfile->netfid); 1646 rc = CIFSSMBFlush(xid, tcon, smbfile->netfid);
@@ -1750,7 +1725,6 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
1750 1725
1751 xid = GetXid(); 1726 xid = GetXid();
1752 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 1727 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
1753 pTcon = cifs_sb->tcon;
1754 1728
1755 if (file->private_data == NULL) { 1729 if (file->private_data == NULL) {
1756 rc = -EBADF; 1730 rc = -EBADF;
@@ -1758,6 +1732,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
1758 return rc; 1732 return rc;
1759 } 1733 }
1760 open_file = file->private_data; 1734 open_file = file->private_data;
1735 pTcon = tlink_tcon(open_file->tlink);
1761 1736
1762 if ((file->f_flags & O_ACCMODE) == O_WRONLY) 1737 if ((file->f_flags & O_ACCMODE) == O_WRONLY)
1763 cFYI(1, "attempting read on write only file instance"); 1738 cFYI(1, "attempting read on write only file instance");
@@ -1771,9 +1746,8 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
1771 smb_read_data = NULL; 1746 smb_read_data = NULL;
1772 while (rc == -EAGAIN) { 1747 while (rc == -EAGAIN) {
1773 int buf_type = CIFS_NO_BUFFER; 1748 int buf_type = CIFS_NO_BUFFER;
1774 if ((open_file->invalidHandle) && 1749 if (open_file->invalidHandle) {
1775 (!open_file->closePend)) { 1750 rc = cifs_reopen_file(open_file, true);
1776 rc = cifs_reopen_file(file, true);
1777 if (rc != 0) 1751 if (rc != 0)
1778 break; 1752 break;
1779 } 1753 }
@@ -1831,7 +1805,6 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
1831 1805
1832 xid = GetXid(); 1806 xid = GetXid();
1833 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 1807 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
1834 pTcon = cifs_sb->tcon;
1835 1808
1836 if (file->private_data == NULL) { 1809 if (file->private_data == NULL) {
1837 rc = -EBADF; 1810 rc = -EBADF;
@@ -1839,6 +1812,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
1839 return rc; 1812 return rc;
1840 } 1813 }
1841 open_file = file->private_data; 1814 open_file = file->private_data;
1815 pTcon = tlink_tcon(open_file->tlink);
1842 1816
1843 if ((file->f_flags & O_ACCMODE) == O_WRONLY) 1817 if ((file->f_flags & O_ACCMODE) == O_WRONLY)
1844 cFYI(1, "attempting read on write only file instance"); 1818 cFYI(1, "attempting read on write only file instance");
@@ -1857,9 +1831,8 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
1857 } 1831 }
1858 rc = -EAGAIN; 1832 rc = -EAGAIN;
1859 while (rc == -EAGAIN) { 1833 while (rc == -EAGAIN) {
1860 if ((open_file->invalidHandle) && 1834 if (open_file->invalidHandle) {
1861 (!open_file->closePend)) { 1835 rc = cifs_reopen_file(open_file, true);
1862 rc = cifs_reopen_file(file, true);
1863 if (rc != 0) 1836 if (rc != 0)
1864 break; 1837 break;
1865 } 1838 }
@@ -1974,7 +1947,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1974 } 1947 }
1975 open_file = file->private_data; 1948 open_file = file->private_data;
1976 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 1949 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
1977 pTcon = cifs_sb->tcon; 1950 pTcon = tlink_tcon(open_file->tlink);
1978 1951
1979 /* 1952 /*
1980 * Reads as many pages as possible from fscache. Returns -ENOBUFS 1953 * Reads as many pages as possible from fscache. Returns -ENOBUFS
@@ -2022,9 +1995,8 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
2022 read_size, contig_pages); 1995 read_size, contig_pages);
2023 rc = -EAGAIN; 1996 rc = -EAGAIN;
2024 while (rc == -EAGAIN) { 1997 while (rc == -EAGAIN) {
2025 if ((open_file->invalidHandle) && 1998 if (open_file->invalidHandle) {
2026 (!open_file->closePend)) { 1999 rc = cifs_reopen_file(open_file, true);
2027 rc = cifs_reopen_file(file, true);
2028 if (rc != 0) 2000 if (rc != 0)
2029 break; 2001 break;
2030 } 2002 }
@@ -2173,18 +2145,14 @@ static int is_inode_writable(struct cifsInodeInfo *cifs_inode)
2173{ 2145{
2174 struct cifsFileInfo *open_file; 2146 struct cifsFileInfo *open_file;
2175 2147
2176 read_lock(&GlobalSMBSeslock); 2148 spin_lock(&cifs_file_list_lock);
2177 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { 2149 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
2178 if (open_file->closePend) 2150 if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) {
2179 continue; 2151 spin_unlock(&cifs_file_list_lock);
2180 if (open_file->pfile &&
2181 ((open_file->pfile->f_flags & O_RDWR) ||
2182 (open_file->pfile->f_flags & O_WRONLY))) {
2183 read_unlock(&GlobalSMBSeslock);
2184 return 1; 2152 return 1;
2185 } 2153 }
2186 } 2154 }
2187 read_unlock(&GlobalSMBSeslock); 2155 spin_unlock(&cifs_file_list_lock);
2188 return 0; 2156 return 0;
2189} 2157}
2190 2158
@@ -2310,9 +2278,8 @@ void cifs_oplock_break(struct work_struct *work)
2310{ 2278{
2311 struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo, 2279 struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo,
2312 oplock_break); 2280 oplock_break);
2313 struct inode *inode = cfile->pInode; 2281 struct inode *inode = cfile->dentry->d_inode;
2314 struct cifsInodeInfo *cinode = CIFS_I(inode); 2282 struct cifsInodeInfo *cinode = CIFS_I(inode);
2315 struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->mnt->mnt_sb);
2316 int rc, waitrc = 0; 2283 int rc, waitrc = 0;
2317 2284
2318 if (inode && S_ISREG(inode->i_mode)) { 2285 if (inode && S_ISREG(inode->i_mode)) {
@@ -2338,9 +2305,9 @@ void cifs_oplock_break(struct work_struct *work)
2338 * not bother sending an oplock release if session to server still is 2305 * not bother sending an oplock release if session to server still is
2339 * disconnected since oplock already released by the server 2306 * disconnected since oplock already released by the server
2340 */ 2307 */
2341 if (!cfile->closePend && !cfile->oplock_break_cancelled) { 2308 if (!cfile->oplock_break_cancelled) {
2342 rc = CIFSSMBLock(0, cifs_sb->tcon, cfile->netfid, 0, 0, 0, 0, 2309 rc = CIFSSMBLock(0, tlink_tcon(cfile->tlink), cfile->netfid, 0,
2343 LOCKING_ANDX_OPLOCK_RELEASE, false); 2310 0, 0, 0, LOCKING_ANDX_OPLOCK_RELEASE, false);
2344 cFYI(1, "Oplock release rc = %d", rc); 2311 cFYI(1, "Oplock release rc = %d", rc);
2345 } 2312 }
2346 2313
@@ -2349,22 +2316,22 @@ void cifs_oplock_break(struct work_struct *work)
2349 * finished grabbing reference for us. Make sure it's done by 2316 * finished grabbing reference for us. Make sure it's done by
2350 * waiting for GlobalSMSSeslock. 2317 * waiting for GlobalSMSSeslock.
2351 */ 2318 */
2352 write_lock(&GlobalSMBSeslock); 2319 spin_lock(&cifs_file_list_lock);
2353 write_unlock(&GlobalSMBSeslock); 2320 spin_unlock(&cifs_file_list_lock);
2354 2321
2355 cifs_oplock_break_put(cfile); 2322 cifs_oplock_break_put(cfile);
2356} 2323}
2357 2324
2358void cifs_oplock_break_get(struct cifsFileInfo *cfile) 2325void cifs_oplock_break_get(struct cifsFileInfo *cfile)
2359{ 2326{
2360 mntget(cfile->mnt); 2327 cifs_sb_active(cfile->dentry->d_sb);
2361 cifsFileInfo_get(cfile); 2328 cifsFileInfo_get(cfile);
2362} 2329}
2363 2330
2364void cifs_oplock_break_put(struct cifsFileInfo *cfile) 2331void cifs_oplock_break_put(struct cifsFileInfo *cfile)
2365{ 2332{
2366 mntput(cfile->mnt);
2367 cifsFileInfo_put(cfile); 2333 cifsFileInfo_put(cfile);
2334 cifs_sb_deactive(cfile->dentry->d_sb);
2368} 2335}
2369 2336
2370const struct address_space_operations cifs_addr_ops = { 2337const struct address_space_operations cifs_addr_ops = {
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..94979309698a 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;
444 466
445 rc = CIFSSMBQAllEAs(xid, cifs_sb->tcon, path, "SETFILEBITS", 467 tlink = cifs_sb_tlink(cifs_sb);
468 if (IS_ERR(tlink))
469 return PTR_ERR(tlink);
470 tcon = tlink_tcon(tlink);
471
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,
@@ -1660,13 +1755,29 @@ check_inval:
1660} 1755}
1661 1756
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
1769 /*
1770 * If on a multiuser mount without unix extensions, and the
1771 * admin hasn't overridden them, set the ownership to the
1772 * fsuid/fsgid of the current process.
1773 */
1774 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) &&
1775 !tcon->unix_ext) {
1776 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID))
1777 stat->uid = current_fsuid();
1778 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID))
1779 stat->gid = current_fsgid();
1780 }
1670 } 1781 }
1671 return err; 1782 return err;
1672} 1783}
@@ -1708,7 +1819,8 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1708 struct cifsFileInfo *open_file; 1819 struct cifsFileInfo *open_file;
1709 struct cifsInodeInfo *cifsInode = CIFS_I(inode); 1820 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1710 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 1821 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1711 struct cifsTconInfo *pTcon = cifs_sb->tcon; 1822 struct tcon_link *tlink = NULL;
1823 struct cifsTconInfo *pTcon = NULL;
1712 1824
1713 /* 1825 /*
1714 * To avoid spurious oplock breaks from server, in the case of 1826 * To avoid spurious oplock breaks from server, in the case of
@@ -1719,10 +1831,11 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1719 * writebehind data than the SMB timeout for the SetPathInfo 1831 * writebehind data than the SMB timeout for the SetPathInfo
1720 * request would allow 1832 * request would allow
1721 */ 1833 */
1722 open_file = find_writable_file(cifsInode); 1834 open_file = find_writable_file(cifsInode, true);
1723 if (open_file) { 1835 if (open_file) {
1724 __u16 nfid = open_file->netfid; 1836 __u16 nfid = open_file->netfid;
1725 __u32 npid = open_file->pid; 1837 __u32 npid = open_file->pid;
1838 pTcon = tlink_tcon(open_file->tlink);
1726 rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid, 1839 rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid,
1727 npid, false); 1840 npid, false);
1728 cifsFileInfo_put(open_file); 1841 cifsFileInfo_put(open_file);
@@ -1737,6 +1850,13 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1737 rc = -EINVAL; 1850 rc = -EINVAL;
1738 1851
1739 if (rc != 0) { 1852 if (rc != 0) {
1853 if (pTcon == NULL) {
1854 tlink = cifs_sb_tlink(cifs_sb);
1855 if (IS_ERR(tlink))
1856 return PTR_ERR(tlink);
1857 pTcon = tlink_tcon(tlink);
1858 }
1859
1740 /* Set file size by pathname rather than by handle 1860 /* Set file size by pathname rather than by handle
1741 either because no valid, writeable file handle for 1861 either because no valid, writeable file handle for
1742 it was found or because there was an error setting 1862 it was found or because there was an error setting
@@ -1766,6 +1886,8 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1766 CIFSSMBClose(xid, pTcon, netfid); 1886 CIFSSMBClose(xid, pTcon, netfid);
1767 } 1887 }
1768 } 1888 }
1889 if (tlink)
1890 cifs_put_tlink(tlink);
1769 } 1891 }
1770 1892
1771 if (rc == 0) { 1893 if (rc == 0) {
@@ -1786,7 +1908,8 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
1786 struct inode *inode = direntry->d_inode; 1908 struct inode *inode = direntry->d_inode;
1787 struct cifsInodeInfo *cifsInode = CIFS_I(inode); 1909 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1788 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 1910 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1789 struct cifsTconInfo *pTcon = cifs_sb->tcon; 1911 struct tcon_link *tlink;
1912 struct cifsTconInfo *pTcon;
1790 struct cifs_unix_set_info_args *args = NULL; 1913 struct cifs_unix_set_info_args *args = NULL;
1791 struct cifsFileInfo *open_file; 1914 struct cifsFileInfo *open_file;
1792 1915
@@ -1873,17 +1996,25 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
1873 args->ctime = NO_CHANGE_64; 1996 args->ctime = NO_CHANGE_64;
1874 1997
1875 args->device = 0; 1998 args->device = 0;
1876 open_file = find_writable_file(cifsInode); 1999 open_file = find_writable_file(cifsInode, true);
1877 if (open_file) { 2000 if (open_file) {
1878 u16 nfid = open_file->netfid; 2001 u16 nfid = open_file->netfid;
1879 u32 npid = open_file->pid; 2002 u32 npid = open_file->pid;
2003 pTcon = tlink_tcon(open_file->tlink);
1880 rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid); 2004 rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid);
1881 cifsFileInfo_put(open_file); 2005 cifsFileInfo_put(open_file);
1882 } else { 2006 } else {
2007 tlink = cifs_sb_tlink(cifs_sb);
2008 if (IS_ERR(tlink)) {
2009 rc = PTR_ERR(tlink);
2010 goto out;
2011 }
2012 pTcon = tlink_tcon(tlink);
1883 rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args, 2013 rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args,
1884 cifs_sb->local_nls, 2014 cifs_sb->local_nls,
1885 cifs_sb->mnt_cifs_flags & 2015 cifs_sb->mnt_cifs_flags &
1886 CIFS_MOUNT_MAP_SPECIAL_CHR); 2016 CIFS_MOUNT_MAP_SPECIAL_CHR);
2017 cifs_put_tlink(tlink);
1887 } 2018 }
1888 2019
1889 if (rc) 2020 if (rc)
@@ -2064,7 +2195,7 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs)
2064{ 2195{
2065 struct inode *inode = direntry->d_inode; 2196 struct inode *inode = direntry->d_inode;
2066 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 2197 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
2067 struct cifsTconInfo *pTcon = cifs_sb->tcon; 2198 struct cifsTconInfo *pTcon = cifs_sb_master_tcon(cifs_sb);
2068 2199
2069 if (pTcon->unix_ext) 2200 if (pTcon->unix_ext)
2070 return cifs_setattr_unix(direntry, attrs); 2201 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..1c681f6a6803 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -347,7 +347,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
347 if (current_fsuid() != treeCon->ses->linux_uid) { 347 if (current_fsuid() != treeCon->ses->linux_uid) {
348 cFYI(1, "Multiuser mode and UID " 348 cFYI(1, "Multiuser mode and UID "
349 "did not match tcon uid"); 349 "did not match tcon uid");
350 read_lock(&cifs_tcp_ses_lock); 350 spin_lock(&cifs_tcp_ses_lock);
351 list_for_each(temp_item, &treeCon->ses->server->smb_ses_list) { 351 list_for_each(temp_item, &treeCon->ses->server->smb_ses_list) {
352 ses = list_entry(temp_item, struct cifsSesInfo, smb_ses_list); 352 ses = list_entry(temp_item, struct cifsSesInfo, smb_ses_list);
353 if (ses->linux_uid == current_fsuid()) { 353 if (ses->linux_uid == current_fsuid()) {
@@ -361,7 +361,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
361 } 361 }
362 } 362 }
363 } 363 }
364 read_unlock(&cifs_tcp_ses_lock); 364 spin_unlock(&cifs_tcp_ses_lock);
365 } 365 }
366 } 366 }
367 } 367 }
@@ -551,7 +551,7 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
551 return false; 551 return false;
552 552
553 /* look up tcon based on tid & uid */ 553 /* look up tcon based on tid & uid */
554 read_lock(&cifs_tcp_ses_lock); 554 spin_lock(&cifs_tcp_ses_lock);
555 list_for_each(tmp, &srv->smb_ses_list) { 555 list_for_each(tmp, &srv->smb_ses_list) {
556 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list); 556 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
557 list_for_each(tmp1, &ses->tcon_list) { 557 list_for_each(tmp1, &ses->tcon_list) {
@@ -560,25 +560,15 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
560 continue; 560 continue;
561 561
562 cifs_stats_inc(&tcon->num_oplock_brks); 562 cifs_stats_inc(&tcon->num_oplock_brks);
563 read_lock(&GlobalSMBSeslock); 563 spin_lock(&cifs_file_list_lock);
564 list_for_each(tmp2, &tcon->openFileList) { 564 list_for_each(tmp2, &tcon->openFileList) {
565 netfile = list_entry(tmp2, struct cifsFileInfo, 565 netfile = list_entry(tmp2, struct cifsFileInfo,
566 tlist); 566 tlist);
567 if (pSMB->Fid != netfile->netfid) 567 if (pSMB->Fid != netfile->netfid)
568 continue; 568 continue;
569 569
570 /*
571 * don't do anything if file is about to be
572 * closed anyway.
573 */
574 if (netfile->closePend) {
575 read_unlock(&GlobalSMBSeslock);
576 read_unlock(&cifs_tcp_ses_lock);
577 return true;
578 }
579
580 cFYI(1, "file id match, oplock break"); 570 cFYI(1, "file id match, oplock break");
581 pCifsInode = CIFS_I(netfile->pInode); 571 pCifsInode = CIFS_I(netfile->dentry->d_inode);
582 pCifsInode->clientCanCacheAll = false; 572 pCifsInode->clientCanCacheAll = false;
583 if (pSMB->OplockLevel == 0) 573 if (pSMB->OplockLevel == 0)
584 pCifsInode->clientCanCacheRead = false; 574 pCifsInode->clientCanCacheRead = false;
@@ -594,17 +584,17 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
594 cifs_oplock_break_get(netfile); 584 cifs_oplock_break_get(netfile);
595 netfile->oplock_break_cancelled = false; 585 netfile->oplock_break_cancelled = false;
596 586
597 read_unlock(&GlobalSMBSeslock); 587 spin_unlock(&cifs_file_list_lock);
598 read_unlock(&cifs_tcp_ses_lock); 588 spin_unlock(&cifs_tcp_ses_lock);
599 return true; 589 return true;
600 } 590 }
601 read_unlock(&GlobalSMBSeslock); 591 spin_unlock(&cifs_file_list_lock);
602 read_unlock(&cifs_tcp_ses_lock); 592 spin_unlock(&cifs_tcp_ses_lock);
603 cFYI(1, "No matching file for oplock break"); 593 cFYI(1, "No matching file for oplock break");
604 return true; 594 return true;
605 } 595 }
606 } 596 }
607 read_unlock(&cifs_tcp_ses_lock); 597 spin_unlock(&cifs_tcp_ses_lock);
608 cFYI(1, "Can not process oplock break for non-existent connection"); 598 cFYI(1, "Can not process oplock break for non-existent connection");
609 return true; 599 return true;
610} 600}
@@ -729,6 +719,6 @@ cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb)
729 "properly. Hardlinks will not be recognized on this " 719 "properly. Hardlinks will not be recognized on this "
730 "mount. Consider mounting with the \"noserverino\" " 720 "mount. Consider mounting with the \"noserverino\" "
731 "option to silence this message.", 721 "option to silence this message.",
732 cifs_sb->tcon->treeName); 722 cifs_sb_master_tcon(cifs_sb)->treeName);
733 } 723 }
734} 724}
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..ef7bb7b50f58 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
@@ -525,14 +528,14 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
525 (index_to_find < first_entry_in_buffer)) { 528 (index_to_find < first_entry_in_buffer)) {
526 /* close and restart search */ 529 /* close and restart search */
527 cFYI(1, "search backing up - close and restart search"); 530 cFYI(1, "search backing up - close and restart search");
528 write_lock(&GlobalSMBSeslock); 531 spin_lock(&cifs_file_list_lock);
529 if (!cifsFile->srch_inf.endOfSearch && 532 if (!cifsFile->srch_inf.endOfSearch &&
530 !cifsFile->invalidHandle) { 533 !cifsFile->invalidHandle) {
531 cifsFile->invalidHandle = true; 534 cifsFile->invalidHandle = true;
532 write_unlock(&GlobalSMBSeslock); 535 spin_unlock(&cifs_file_list_lock);
533 CIFSFindClose(xid, pTcon, cifsFile->netfid); 536 CIFSFindClose(xid, pTcon, cifsFile->netfid);
534 } else 537 } else
535 write_unlock(&GlobalSMBSeslock); 538 spin_unlock(&cifs_file_list_lock);
536 if (cifsFile->srch_inf.ntwrk_buf_start) { 539 if (cifsFile->srch_inf.ntwrk_buf_start) {
537 cFYI(1, "freeing SMB ff cache buf on search rewind"); 540 cFYI(1, "freeing SMB ff cache buf on search rewind");
538 if (cifsFile->srch_inf.smallBuf) 541 if (cifsFile->srch_inf.smallBuf)
@@ -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,17 @@ 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; 792
781 if (pTcon == NULL) 793 /*
782 return -EINVAL; 794 * Ensure FindFirst doesn't fail before doing filldir() for '.' and
795 * '..'. Otherwise we won't be able to notify VFS in case of failure.
796 */
797 if (file->private_data == NULL) {
798 rc = initiate_cifs_search(xid, file);
799 cFYI(1, "initiate cifs search rc %d", rc);
800 if (rc)
801 goto rddir2_exit;
802 }
783 803
784 switch ((int) file->f_pos) { 804 switch ((int) file->f_pos) {
785 case 0: 805 case 0:
@@ -805,14 +825,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
805 if after then keep searching till find it */ 825 if after then keep searching till find it */
806 826
807 if (file->private_data == NULL) { 827 if (file->private_data == NULL) {
808 rc = initiate_cifs_search(xid, file);
809 cFYI(1, "initiate cifs search rc %d", rc);
810 if (rc) {
811 FreeXid(xid);
812 return rc;
813 }
814 }
815 if (file->private_data == NULL) {
816 rc = -EINVAL; 828 rc = -EINVAL;
817 FreeXid(xid); 829 FreeXid(xid);
818 return rc; 830 return rc;
@@ -829,6 +841,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
829 CIFSFindClose(xid, pTcon, cifsFile->netfid); 841 CIFSFindClose(xid, pTcon, cifsFile->netfid);
830 } */ 842 } */
831 843
844 pTcon = tlink_tcon(cifsFile->tlink);
832 rc = find_cifs_entry(xid, pTcon, file, 845 rc = find_cifs_entry(xid, pTcon, file,
833 &current_entry, &num_to_fill); 846 &current_entry, &num_to_fill);
834 if (rc) { 847 if (rc) {
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 0a57cb7db5dd..2a11efd96592 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -80,7 +80,7 @@ static __le16 get_next_vcnum(struct cifsSesInfo *ses)
80 if (max_vcs < 2) 80 if (max_vcs < 2)
81 max_vcs = 0xFFFF; 81 max_vcs = 0xFFFF;
82 82
83 write_lock(&cifs_tcp_ses_lock); 83 spin_lock(&cifs_tcp_ses_lock);
84 if ((ses->need_reconnect) && is_first_ses_reconnect(ses)) 84 if ((ses->need_reconnect) && is_first_ses_reconnect(ses))
85 goto get_vc_num_exit; /* vcnum will be zero */ 85 goto get_vc_num_exit; /* vcnum will be zero */
86 for (i = ses->server->srv_count - 1; i < max_vcs; i++) { 86 for (i = ses->server->srv_count - 1; i < max_vcs; i++) {
@@ -112,7 +112,7 @@ static __le16 get_next_vcnum(struct cifsSesInfo *ses)
112 vcnum = i; 112 vcnum = i;
113 ses->vcnum = vcnum; 113 ses->vcnum = vcnum;
114get_vc_num_exit: 114get_vc_num_exit:
115 write_unlock(&cifs_tcp_ses_lock); 115 spin_unlock(&cifs_tcp_ses_lock);
116 116
117 return cpu_to_le16(vcnum); 117 return cpu_to_le16(vcnum);
118} 118}
@@ -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)) {
@@ -399,12 +402,25 @@ static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
399 return -EINVAL; 402 return -EINVAL;
400 } 403 }
401 404
402 memcpy(ses->server->cryptKey, pblob->Challenge, CIFS_CRYPTO_KEY_SIZE); 405 memcpy(ses->cryptKey, pblob->Challenge, CIFS_CRYPTO_KEY_SIZE);
403 /* BB we could decode pblob->NegotiateFlags; some may be useful */ 406 /* BB we could decode pblob->NegotiateFlags; some may be useful */
404 /* In particular we can examine sign flags */ 407 /* In particular we can examine sign flags */
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;
@@ -448,13 +464,16 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
448 maximum possible size is fixed and small, making this approach cleaner. 464 maximum possible size is fixed and small, making this approach cleaner.
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,
467 u16 *buflen,
451 struct cifsSesInfo *ses, 468 struct cifsSesInfo *ses,
452 const struct nls_table *nls_cp, bool first) 469 const struct nls_table *nls_cp)
453{ 470{
471 int rc;
472 unsigned int size;
454 AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer; 473 AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer;
455 __u32 flags; 474 __u32 flags;
456 unsigned char *tmp; 475 unsigned char *tmp;
457 char ntlm_session_key[CIFS_SESS_KEY_SIZE]; 476 struct ntlmv2_resp ntlmv2_response = {};
458 477
459 memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8); 478 memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
460 sec_blob->MessageType = NtLmAuthenticate; 479 sec_blob->MessageType = NtLmAuthenticate;
@@ -462,7 +481,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
462 flags = NTLMSSP_NEGOTIATE_56 | 481 flags = NTLMSSP_NEGOTIATE_56 |
463 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO | 482 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
464 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | 483 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
465 NTLMSSP_NEGOTIATE_NT_ONLY | NTLMSSP_NEGOTIATE_NTLM; 484 NTLMSSP_NEGOTIATE_NTLM;
466 if (ses->server->secMode & 485 if (ses->server->secMode &
467 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 486 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
468 flags |= NTLMSSP_NEGOTIATE_SIGN; 487 flags |= NTLMSSP_NEGOTIATE_SIGN;
@@ -477,19 +496,26 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
477 sec_blob->LmChallengeResponse.Length = 0; 496 sec_blob->LmChallengeResponse.Length = 0;
478 sec_blob->LmChallengeResponse.MaximumLength = 0; 497 sec_blob->LmChallengeResponse.MaximumLength = 0;
479 498
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); 499 sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer);
488 sec_blob->NtChallengeResponse.Length = cpu_to_le16(CIFS_SESS_KEY_SIZE); 500 rc = setup_ntlmv2_rsp(ses, (char *)&ntlmv2_response, nls_cp);
489 sec_blob->NtChallengeResponse.MaximumLength = 501 if (rc) {
490 cpu_to_le16(CIFS_SESS_KEY_SIZE); 502 cERROR(1, "Error %d during NTLMSSP authentication", rc);
503 goto setup_ntlmv2_ret;
504 }
505 size = sizeof(struct ntlmv2_resp);
506 memcpy(tmp, (char *)&ntlmv2_response, size);
507 tmp += size;
508 if (ses->tilen > 0) {
509 memcpy(tmp, ses->tiblob, ses->tilen);
510 tmp += ses->tilen;
511 }
491 512
492 tmp += CIFS_SESS_KEY_SIZE; 513 sec_blob->NtChallengeResponse.Length = cpu_to_le16(size + ses->tilen);
514 sec_blob->NtChallengeResponse.MaximumLength =
515 cpu_to_le16(size + ses->tilen);
516 kfree(ses->tiblob);
517 ses->tiblob = NULL;
518 ses->tilen = 0;
493 519
494 if (ses->domainName == NULL) { 520 if (ses->domainName == NULL) {
495 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); 521 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
@@ -501,7 +527,6 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
501 len = cifs_strtoUCS((__le16 *)tmp, ses->domainName, 527 len = cifs_strtoUCS((__le16 *)tmp, ses->domainName,
502 MAX_USERNAME_SIZE, nls_cp); 528 MAX_USERNAME_SIZE, nls_cp);
503 len *= 2; /* unicode is 2 bytes each */ 529 len *= 2; /* unicode is 2 bytes each */
504 len += 2; /* trailing null */
505 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); 530 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
506 sec_blob->DomainName.Length = cpu_to_le16(len); 531 sec_blob->DomainName.Length = cpu_to_le16(len);
507 sec_blob->DomainName.MaximumLength = cpu_to_le16(len); 532 sec_blob->DomainName.MaximumLength = cpu_to_le16(len);
@@ -518,7 +543,6 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
518 len = cifs_strtoUCS((__le16 *)tmp, ses->userName, 543 len = cifs_strtoUCS((__le16 *)tmp, ses->userName,
519 MAX_USERNAME_SIZE, nls_cp); 544 MAX_USERNAME_SIZE, nls_cp);
520 len *= 2; /* unicode is 2 bytes each */ 545 len *= 2; /* unicode is 2 bytes each */
521 len += 2; /* trailing null */
522 sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer); 546 sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
523 sec_blob->UserName.Length = cpu_to_le16(len); 547 sec_blob->UserName.Length = cpu_to_le16(len);
524 sec_blob->UserName.MaximumLength = cpu_to_le16(len); 548 sec_blob->UserName.MaximumLength = cpu_to_le16(len);
@@ -533,7 +557,10 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
533 sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer); 557 sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
534 sec_blob->SessionKey.Length = 0; 558 sec_blob->SessionKey.Length = 0;
535 sec_blob->SessionKey.MaximumLength = 0; 559 sec_blob->SessionKey.MaximumLength = 0;
536 return tmp - pbuffer; 560
561setup_ntlmv2_ret:
562 *buflen = tmp - pbuffer;
563 return rc;
537} 564}
538 565
539 566
@@ -545,19 +572,6 @@ static void setup_ntlmssp_neg_req(SESSION_SETUP_ANDX *pSMB,
545 572
546 return; 573 return;
547} 574}
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 575#endif
562 576
563int 577int
@@ -579,15 +593,12 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
579 int bytes_remaining; 593 int bytes_remaining;
580 struct key *spnego_key = NULL; 594 struct key *spnego_key = NULL;
581 __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */ 595 __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */
582 bool first_time; 596 u16 blob_len;
597 char *ntlmsspblob = NULL;
583 598
584 if (ses == NULL) 599 if (ses == NULL)
585 return -EINVAL; 600 return -EINVAL;
586 601
587 read_lock(&cifs_tcp_ses_lock);
588 first_time = is_first_ses_reconnect(ses);
589 read_unlock(&cifs_tcp_ses_lock);
590
591 type = ses->server->secType; 602 type = ses->server->secType;
592 603
593 cFYI(1, "sess setup type %d", type); 604 cFYI(1, "sess setup type %d", type);
@@ -658,7 +669,7 @@ ssetup_ntlmssp_authenticate:
658 /* BB calculate hash with password */ 669 /* BB calculate hash with password */
659 /* and copy into bcc */ 670 /* and copy into bcc */
660 671
661 calc_lanman_hash(ses->password, ses->server->cryptKey, 672 calc_lanman_hash(ses->password, ses->cryptKey,
662 ses->server->secMode & SECMODE_PW_ENCRYPT ? 673 ses->server->secMode & SECMODE_PW_ENCRYPT ?
663 true : false, lnm_session_key); 674 true : false, lnm_session_key);
664 675
@@ -685,15 +696,11 @@ ssetup_ntlmssp_authenticate:
685 cpu_to_le16(CIFS_SESS_KEY_SIZE); 696 cpu_to_le16(CIFS_SESS_KEY_SIZE);
686 697
687 /* calculate session key */ 698 /* calculate session key */
688 SMBNTencrypt(ses->password, ses->server->cryptKey, 699 SMBNTencrypt(ses->password, ses->cryptKey, ntlm_session_key);
689 ntlm_session_key);
690 700
691 if (first_time) /* should this be moved into common code 701 cifs_calculate_session_key(&ses->auth_key,
692 with similar ntlmv2 path? */ 702 ntlm_session_key, ses->password);
693 cifs_calculate_mac_key(&ses->server->mac_signing_key,
694 ntlm_session_key, ses->password);
695 /* copy session key */ 703 /* copy session key */
696
697 memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE); 704 memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);
698 bcc_ptr += CIFS_SESS_KEY_SIZE; 705 bcc_ptr += CIFS_SESS_KEY_SIZE;
699 memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE); 706 memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);
@@ -725,16 +732,31 @@ ssetup_ntlmssp_authenticate:
725 pSMB->req_no_secext.CaseInsensitivePasswordLength = 0; 732 pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
726 /* cpu_to_le16(LM2_SESS_KEY_SIZE); */ 733 /* cpu_to_le16(LM2_SESS_KEY_SIZE); */
727 734
728 pSMB->req_no_secext.CaseSensitivePasswordLength =
729 cpu_to_le16(sizeof(struct ntlmv2_resp));
730
731 /* calculate session key */ 735 /* calculate session key */
732 setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp); 736 rc = setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp);
733 /* FIXME: calculate MAC key */ 737 if (rc) {
738 cERROR(1, "Error %d during NTLMv2 authentication", rc);
739 kfree(v2_sess_key);
740 goto ssetup_exit;
741 }
734 memcpy(bcc_ptr, (char *)v2_sess_key, 742 memcpy(bcc_ptr, (char *)v2_sess_key,
735 sizeof(struct ntlmv2_resp)); 743 sizeof(struct ntlmv2_resp));
736 bcc_ptr += sizeof(struct ntlmv2_resp); 744 bcc_ptr += sizeof(struct ntlmv2_resp);
737 kfree(v2_sess_key); 745 kfree(v2_sess_key);
746 /* set case sensitive password length after tilen may get
747 * assigned, tilen is 0 otherwise.
748 */
749 pSMB->req_no_secext.CaseSensitivePasswordLength =
750 cpu_to_le16(sizeof(struct ntlmv2_resp) + ses->tilen);
751 if (ses->tilen > 0) {
752 memcpy(bcc_ptr, ses->tiblob, ses->tilen);
753 bcc_ptr += ses->tilen;
754 /* we never did allocate ses->domainName to free */
755 kfree(ses->tiblob);
756 ses->tiblob = NULL;
757 ses->tilen = 0;
758 }
759
738 if (ses->capabilities & CAP_UNICODE) { 760 if (ses->capabilities & CAP_UNICODE) {
739 if (iov[0].iov_len % 2) { 761 if (iov[0].iov_len % 2) {
740 *bcc_ptr = 0; 762 *bcc_ptr = 0;
@@ -765,17 +787,14 @@ ssetup_ntlmssp_authenticate:
765 } 787 }
766 /* bail out if key is too long */ 788 /* bail out if key is too long */
767 if (msg->sesskey_len > 789 if (msg->sesskey_len >
768 sizeof(ses->server->mac_signing_key.data.krb5)) { 790 sizeof(ses->auth_key.data.krb5)) {
769 cERROR(1, "Kerberos signing key too long (%u bytes)", 791 cERROR(1, "Kerberos signing key too long (%u bytes)",
770 msg->sesskey_len); 792 msg->sesskey_len);
771 rc = -EOVERFLOW; 793 rc = -EOVERFLOW;
772 goto ssetup_exit; 794 goto ssetup_exit;
773 } 795 }
774 if (first_time) { 796 ses->auth_key.len = msg->sesskey_len;
775 ses->server->mac_signing_key.len = msg->sesskey_len; 797 memcpy(ses->auth_key.data.krb5, msg->data, msg->sesskey_len);
776 memcpy(ses->server->mac_signing_key.data.krb5,
777 msg->data, msg->sesskey_len);
778 }
779 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; 798 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
780 capabilities |= CAP_EXTENDED_SECURITY; 799 capabilities |= CAP_EXTENDED_SECURITY;
781 pSMB->req.Capabilities = cpu_to_le32(capabilities); 800 pSMB->req.Capabilities = cpu_to_le32(capabilities);
@@ -815,12 +834,30 @@ ssetup_ntlmssp_authenticate:
815 if (phase == NtLmNegotiate) { 834 if (phase == NtLmNegotiate) {
816 setup_ntlmssp_neg_req(pSMB, ses); 835 setup_ntlmssp_neg_req(pSMB, ses);
817 iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE); 836 iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE);
837 iov[1].iov_base = &pSMB->req.SecurityBlob[0];
818 } else if (phase == NtLmAuthenticate) { 838 } else if (phase == NtLmAuthenticate) {
819 int blob_len; 839 /* 5 is an empirical value, large enought to
820 blob_len = setup_ntlmssp_auth_req(pSMB, ses, 840 * hold authenticate message, max 10 of
821 nls_cp, 841 * av paris, doamin,user,workstation mames,
822 first_time); 842 * flags etc..
843 */
844 ntlmsspblob = kmalloc(
845 5*sizeof(struct _AUTHENTICATE_MESSAGE),
846 GFP_KERNEL);
847 if (!ntlmsspblob) {
848 cERROR(1, "Can't allocate NTLMSSP");
849 rc = -ENOMEM;
850 goto ssetup_exit;
851 }
852
853 rc = build_ntlmssp_auth_blob(ntlmsspblob,
854 &blob_len, ses, nls_cp);
855 if (rc)
856 goto ssetup_exit;
823 iov[1].iov_len = blob_len; 857 iov[1].iov_len = blob_len;
858 iov[1].iov_base = ntlmsspblob;
859 pSMB->req.SecurityBlobLength =
860 cpu_to_le16(blob_len);
824 /* Make sure that we tell the server that we 861 /* Make sure that we tell the server that we
825 are using the uid that it just gave us back 862 are using the uid that it just gave us back
826 on the response (challenge) */ 863 on the response (challenge) */
@@ -830,7 +867,6 @@ ssetup_ntlmssp_authenticate:
830 rc = -ENOSYS; 867 rc = -ENOSYS;
831 goto ssetup_exit; 868 goto ssetup_exit;
832 } 869 }
833 iov[1].iov_base = &pSMB->req.SecurityBlob[0];
834 /* unicode strings must be word aligned */ 870 /* unicode strings must be word aligned */
835 if ((iov[0].iov_len + iov[1].iov_len) % 2) { 871 if ((iov[0].iov_len + iov[1].iov_len) % 2) {
836 *bcc_ptr = 0; 872 *bcc_ptr = 0;
@@ -895,7 +931,6 @@ ssetup_ntlmssp_authenticate:
895 bcc_ptr = pByteArea(smb_buf); 931 bcc_ptr = pByteArea(smb_buf);
896 932
897 if (smb_buf->WordCount == 4) { 933 if (smb_buf->WordCount == 4) {
898 __u16 blob_len;
899 blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength); 934 blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
900 if (blob_len > bytes_remaining) { 935 if (blob_len > bytes_remaining) {
901 cERROR(1, "bad security blob length %d", blob_len); 936 cERROR(1, "bad security blob length %d", blob_len);
@@ -931,6 +966,8 @@ ssetup_exit:
931 key_put(spnego_key); 966 key_put(spnego_key);
932 } 967 }
933 kfree(str_area); 968 kfree(str_area);
969 kfree(ntlmsspblob);
970 ntlmsspblob = NULL;
934 if (resp_buf_type == CIFS_SMALL_BUFFER) { 971 if (resp_buf_type == CIFS_SMALL_BUFFER) {
935 cFYI(1, "ssetup freeing small buf %p", iov[0].iov_base); 972 cFYI(1, "ssetup freeing small buf %p", iov[0].iov_base);
936 cifs_small_buf_release(iov[0].iov_base); 973 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}