aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2010-09-29 19:51:11 -0400
committerSteve French <sfrench@us.ibm.com>2010-10-06 12:12:44 -0400
commit7ffec372458d163492e56e663a1b3a2d7be0a0a2 (patch)
treee404e3d1000ff41e9b27d0ecb4d6a47187e110d7 /fs/cifs
parentf3983c2133e9bea9c8b4f690737d15e3e9b02491 (diff)
cifs: add refcounted and timestamped container for holding tcons
Eventually, we'll need to track the use of tcons on a per-sb basis, so that we know when it's ok to tear them down. Begin this conversion by adding a new "tcon_link" struct and accessors that get it. For now, the core data structures are untouched -- cifs_sb still just points to a single tcon and the pointers are just cast to deal with the accessor functions. A later patch will flesh this out. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cifs_dfs_ref.c21
-rw-r--r--fs/cifs/cifsacl.c42
-rw-r--r--fs/cifs/cifsglob.h51
-rw-r--r--fs/cifs/dir.c65
-rw-r--r--fs/cifs/file.c9
-rw-r--r--fs/cifs/inode.c157
-rw-r--r--fs/cifs/link.c87
-rw-r--r--fs/cifs/readdir.c32
-rw-r--r--fs/cifs/xattr.c60
9 files changed, 376 insertions, 148 deletions
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
index f1e13ea45a17..f4aab6f01174 100644
--- a/fs/cifs/cifs_dfs_ref.c
+++ b/fs/cifs/cifs_dfs_ref.c
@@ -306,6 +306,7 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
306 int xid, i; 306 int xid, i;
307 int rc = 0; 307 int rc = 0;
308 struct vfsmount *mnt = ERR_PTR(-ENOENT); 308 struct vfsmount *mnt = ERR_PTR(-ENOENT);
309 struct tcon_link *tlink;
309 310
310 cFYI(1, "in %s", __func__); 311 cFYI(1, "in %s", __func__);
311 BUG_ON(IS_ROOT(dentry)); 312 BUG_ON(IS_ROOT(dentry));
@@ -315,14 +316,6 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
315 dput(nd->path.dentry); 316 dput(nd->path.dentry);
316 nd->path.dentry = dget(dentry); 317 nd->path.dentry = dget(dentry);
317 318
318 cifs_sb = CIFS_SB(dentry->d_inode->i_sb);
319 ses = cifs_sb_tcon(cifs_sb)->ses;
320
321 if (!ses) {
322 rc = -EINVAL;
323 goto out_err;
324 }
325
326 /* 319 /*
327 * The MSDFS spec states that paths in DFS referral requests and 320 * The MSDFS spec states that paths in DFS referral requests and
328 * responses must be prefixed by a single '\' character instead of 321 * responses must be prefixed by a single '\' character instead of
@@ -335,10 +328,20 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
335 goto out_err; 328 goto out_err;
336 } 329 }
337 330
338 rc = get_dfs_path(xid, ses , full_path + 1, cifs_sb->local_nls, 331 cifs_sb = CIFS_SB(dentry->d_inode->i_sb);
332 tlink = cifs_sb_tlink(cifs_sb);
333 if (IS_ERR(tlink)) {
334 rc = PTR_ERR(tlink);
335 goto out_err;
336 }
337 ses = tlink_tcon(tlink)->ses;
338
339 rc = get_dfs_path(xid, ses, full_path + 1, cifs_sb->local_nls,
339 &num_referrals, &referrals, 340 &num_referrals, &referrals,
340 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 341 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
341 342
343 cifs_put_tlink(tlink);
344
342 for (i = 0; i < num_referrals; i++) { 345 for (i = 0; i < num_referrals; i++) {
343 int len; 346 int len;
344 dump_referral(referrals+i); 347 dump_referral(referrals+i);
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index 32f244909a0d..2647ea410c4c 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(cifs_sb), 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(cifs_sb), 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(cifs_sb), 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(cifs_sb), 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}
@@ -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(cifs_sb), 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(cifs_sb), 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(cifs_sb), 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(cifs_sb), 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
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index c265ebdcd177..cdfd2db4e70d 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -311,6 +311,44 @@ struct cifsTconInfo {
311}; 311};
312 312
313/* 313/*
314 * This is a refcounted and timestamped container for a tcon pointer. The
315 * container holds a tcon reference. It is considered safe to free one of
316 * these when the tl_count goes to 0. The tl_time is the time of the last
317 * "get" on the container.
318 */
319struct tcon_link {
320 spinlock_t tl_lock;
321 u32 tl_count;
322 u64 tl_time;
323 struct cifsTconInfo *tl_tcon;
324};
325
326static inline struct tcon_link *
327cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
328{
329 return (struct tcon_link *)cifs_sb->ptcon;
330}
331
332static inline struct cifsTconInfo *
333tlink_tcon(struct tcon_link *tlink)
334{
335 return (struct cifsTconInfo *)tlink;
336}
337
338static inline void
339cifs_put_tlink(struct tcon_link *tlink)
340{
341 return;
342}
343
344/* This function is always expected to succeed */
345static inline struct cifsTconInfo *
346cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb)
347{
348 return cifs_sb->ptcon;
349}
350
351/*
314 * This info hangs off the cifsFileInfo structure, pointed to by llist. 352 * This info hangs off the cifsFileInfo structure, pointed to by llist.
315 * This is used to track byte stream locks on the file 353 * This is used to track byte stream locks on the file
316 */ 354 */
@@ -413,19 +451,6 @@ CIFS_SB(struct super_block *sb)
413 return sb->s_fs_info; 451 return sb->s_fs_info;
414} 452}
415 453
416static inline struct cifsTconInfo *
417cifs_sb_tcon(struct cifs_sb_info *cifs_sb)
418{
419 return cifs_sb->ptcon;
420}
421
422/* This function is always expected to succeed */
423static inline struct cifsTconInfo *
424cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb)
425{
426 return cifs_sb->ptcon;
427}
428
429static inline char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb) 454static inline char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb)
430{ 455{
431 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) 456 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 23ec28a4c11f..bb3ea06ca6f4 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -137,7 +137,6 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, struct file *file,
137{ 137{
138 struct cifsFileInfo *pCifsFile; 138 struct cifsFileInfo *pCifsFile;
139 struct cifsInodeInfo *pCifsInode; 139 struct cifsInodeInfo *pCifsInode;
140 struct cifs_sb_info *cifs_sb = CIFS_SB(mnt->mnt_sb);
141 140
142 pCifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); 141 pCifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
143 if (pCifsFile == NULL) 142 if (pCifsFile == NULL)
@@ -191,7 +190,8 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
191 __u32 posix_flags = 0; 190 __u32 posix_flags = 0;
192 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 191 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
193 struct cifs_fattr fattr; 192 struct cifs_fattr fattr;
194 struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb); 193 struct tcon_link *tlink;
194 struct cifsTconInfo *tcon;
195 195
196 cFYI(1, "posix open %s", full_path); 196 cFYI(1, "posix open %s", full_path);
197 197
@@ -226,10 +226,20 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
226 posix_flags |= SMB_O_DIRECT; 226 posix_flags |= SMB_O_DIRECT;
227 227
228 mode &= ~current_umask(); 228 mode &= ~current_umask();
229
230 tlink = cifs_sb_tlink(cifs_sb);
231 if (IS_ERR(tlink)) {
232 rc = PTR_ERR(tlink);
233 goto posix_open_ret;
234 }
235
236 tcon = tlink_tcon(tlink);
229 rc = CIFSPOSIXCreate(xid, tcon, posix_flags, mode, pnetfid, presp_data, 237 rc = CIFSPOSIXCreate(xid, tcon, posix_flags, mode, pnetfid, presp_data,
230 poplock, full_path, cifs_sb->local_nls, 238 poplock, full_path, cifs_sb->local_nls,
231 cifs_sb->mnt_cifs_flags & 239 cifs_sb->mnt_cifs_flags &
232 CIFS_MOUNT_MAP_SPECIAL_CHR); 240 CIFS_MOUNT_MAP_SPECIAL_CHR);
241 cifs_put_tlink(tlink);
242
233 if (rc) 243 if (rc)
234 goto posix_open_ret; 244 goto posix_open_ret;
235 245
@@ -290,6 +300,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
290 int desiredAccess = GENERIC_READ | GENERIC_WRITE; 300 int desiredAccess = GENERIC_READ | GENERIC_WRITE;
291 __u16 fileHandle; 301 __u16 fileHandle;
292 struct cifs_sb_info *cifs_sb; 302 struct cifs_sb_info *cifs_sb;
303 struct tcon_link *tlink;
293 struct cifsTconInfo *tcon; 304 struct cifsTconInfo *tcon;
294 char *full_path = NULL; 305 char *full_path = NULL;
295 FILE_ALL_INFO *buf = NULL; 306 FILE_ALL_INFO *buf = NULL;
@@ -299,13 +310,12 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
299 xid = GetXid(); 310 xid = GetXid();
300 311
301 cifs_sb = CIFS_SB(inode->i_sb); 312 cifs_sb = CIFS_SB(inode->i_sb);
302 tcon = cifs_sb_tcon(cifs_sb); 313 tlink = cifs_sb_tlink(cifs_sb);
303 314 if (IS_ERR(tlink)) {
304 full_path = build_path_from_dentry(direntry); 315 FreeXid(xid);
305 if (full_path == NULL) { 316 return PTR_ERR(tlink);
306 rc = -ENOMEM;
307 goto cifs_create_out;
308 } 317 }
318 tcon = tlink_tcon(tlink);
309 319
310 if (oplockEnabled) 320 if (oplockEnabled)
311 oplock = REQ_OPLOCK; 321 oplock = REQ_OPLOCK;
@@ -315,6 +325,12 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
315 else 325 else
316 oflags = FMODE_READ | SMB_O_CREAT; 326 oflags = FMODE_READ | SMB_O_CREAT;
317 327
328 full_path = build_path_from_dentry(direntry);
329 if (full_path == NULL) {
330 rc = -ENOMEM;
331 goto cifs_create_out;
332 }
333
318 if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) && 334 if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) &&
319 (CIFS_UNIX_POSIX_PATH_OPS_CAP & 335 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
320 le64_to_cpu(tcon->fsUnixInfo.Capability))) { 336 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
@@ -481,6 +497,7 @@ cifs_create_set_dentry:
481cifs_create_out: 497cifs_create_out:
482 kfree(buf); 498 kfree(buf);
483 kfree(full_path); 499 kfree(full_path);
500 cifs_put_tlink(tlink);
484 FreeXid(xid); 501 FreeXid(xid);
485 return rc; 502 return rc;
486} 503}
@@ -491,6 +508,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
491 int rc = -EPERM; 508 int rc = -EPERM;
492 int xid; 509 int xid;
493 struct cifs_sb_info *cifs_sb; 510 struct cifs_sb_info *cifs_sb;
511 struct tcon_link *tlink;
494 struct cifsTconInfo *pTcon; 512 struct cifsTconInfo *pTcon;
495 char *full_path = NULL; 513 char *full_path = NULL;
496 struct inode *newinode = NULL; 514 struct inode *newinode = NULL;
@@ -503,10 +521,14 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
503 if (!old_valid_dev(device_number)) 521 if (!old_valid_dev(device_number))
504 return -EINVAL; 522 return -EINVAL;
505 523
506 xid = GetXid();
507
508 cifs_sb = CIFS_SB(inode->i_sb); 524 cifs_sb = CIFS_SB(inode->i_sb);
509 pTcon = cifs_sb_tcon(cifs_sb); 525 tlink = cifs_sb_tlink(cifs_sb);
526 if (IS_ERR(tlink))
527 return PTR_ERR(tlink);
528
529 pTcon = tlink_tcon(tlink);
530
531 xid = GetXid();
510 532
511 full_path = build_path_from_dentry(direntry); 533 full_path = build_path_from_dentry(direntry);
512 if (full_path == NULL) { 534 if (full_path == NULL) {
@@ -606,6 +628,7 @@ mknod_out:
606 kfree(full_path); 628 kfree(full_path);
607 kfree(buf); 629 kfree(buf);
608 FreeXid(xid); 630 FreeXid(xid);
631 cifs_put_tlink(tlink);
609 return rc; 632 return rc;
610} 633}
611 634
@@ -619,6 +642,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
619 __u16 fileHandle = 0; 642 __u16 fileHandle = 0;
620 bool posix_open = false; 643 bool posix_open = false;
621 struct cifs_sb_info *cifs_sb; 644 struct cifs_sb_info *cifs_sb;
645 struct tcon_link *tlink;
622 struct cifsTconInfo *pTcon; 646 struct cifsTconInfo *pTcon;
623 struct cifsFileInfo *cfile; 647 struct cifsFileInfo *cfile;
624 struct inode *newInode = NULL; 648 struct inode *newInode = NULL;
@@ -633,7 +657,12 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
633 /* check whether path exists */ 657 /* check whether path exists */
634 658
635 cifs_sb = CIFS_SB(parent_dir_inode->i_sb); 659 cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
636 pTcon = cifs_sb_tcon(cifs_sb); 660 tlink = cifs_sb_tlink(cifs_sb);
661 if (IS_ERR(tlink)) {
662 FreeXid(xid);
663 return (struct dentry *)tlink;
664 }
665 pTcon = tlink_tcon(tlink);
637 666
638 /* 667 /*
639 * Don't allow the separator character in a path component. 668 * Don't allow the separator character in a path component.
@@ -644,8 +673,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
644 for (i = 0; i < direntry->d_name.len; i++) 673 for (i = 0; i < direntry->d_name.len; i++)
645 if (direntry->d_name.name[i] == '\\') { 674 if (direntry->d_name.name[i] == '\\') {
646 cFYI(1, "Invalid file name"); 675 cFYI(1, "Invalid file name");
647 FreeXid(xid); 676 rc = -EINVAL;
648 return ERR_PTR(-EINVAL); 677 goto lookup_out;
649 } 678 }
650 } 679 }
651 680
@@ -655,7 +684,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
655 */ 684 */
656 if (nd && (nd->flags & LOOKUP_EXCL)) { 685 if (nd && (nd->flags & LOOKUP_EXCL)) {
657 d_instantiate(direntry, NULL); 686 d_instantiate(direntry, NULL);
658 return NULL; 687 rc = 0;
688 goto lookup_out;
659 } 689 }
660 690
661 /* can not grab the rename sem here since it would 691 /* can not grab the rename sem here since it would
@@ -663,8 +693,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
663 in which we already have the sb rename sem */ 693 in which we already have the sb rename sem */
664 full_path = build_path_from_dentry(direntry); 694 full_path = build_path_from_dentry(direntry);
665 if (full_path == NULL) { 695 if (full_path == NULL) {
666 FreeXid(xid); 696 rc = -ENOMEM;
667 return ERR_PTR(-ENOMEM); 697 goto lookup_out;
668 } 698 }
669 699
670 if (direntry->d_inode != NULL) { 700 if (direntry->d_inode != NULL) {
@@ -760,6 +790,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
760 790
761lookup_out: 791lookup_out:
762 kfree(full_path); 792 kfree(full_path);
793 cifs_put_tlink(tlink);
763 FreeXid(xid); 794 FreeXid(xid);
764 return ERR_PTR(rc); 795 return ERR_PTR(rc);
765} 796}
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index de046e183d12..1e375abc5eb3 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -224,6 +224,7 @@ int cifs_open(struct inode *inode, struct file *file)
224 __u32 oplock; 224 __u32 oplock;
225 struct cifs_sb_info *cifs_sb; 225 struct cifs_sb_info *cifs_sb;
226 struct cifsTconInfo *tcon; 226 struct cifsTconInfo *tcon;
227 struct tcon_link *tlink;
227 struct cifsFileInfo *pCifsFile = NULL; 228 struct cifsFileInfo *pCifsFile = NULL;
228 struct cifsInodeInfo *pCifsInode; 229 struct cifsInodeInfo *pCifsInode;
229 char *full_path = NULL; 230 char *full_path = NULL;
@@ -235,7 +236,12 @@ int cifs_open(struct inode *inode, struct file *file)
235 xid = GetXid(); 236 xid = GetXid();
236 237
237 cifs_sb = CIFS_SB(inode->i_sb); 238 cifs_sb = CIFS_SB(inode->i_sb);
238 tcon = cifs_sb_tcon(cifs_sb); 239 tlink = cifs_sb_tlink(cifs_sb);
240 if (IS_ERR(tlink)) {
241 FreeXid(xid);
242 return PTR_ERR(tlink);
243 }
244 tcon = tlink_tcon(tlink);
239 245
240 pCifsInode = CIFS_I(file->f_path.dentry->d_inode); 246 pCifsInode = CIFS_I(file->f_path.dentry->d_inode);
241 247
@@ -402,6 +408,7 @@ out:
402 kfree(buf); 408 kfree(buf);
403 kfree(full_path); 409 kfree(full_path);
404 FreeXid(xid); 410 FreeXid(xid);
411 cifs_put_tlink(tlink);
405 return rc; 412 return rc;
406} 413}
407 414
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index da716d96dae6..aa229692aef1 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -313,16 +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(cifs_sb);
319
320 cFYI(1, "Getting info on %s", full_path); 319 cFYI(1, "Getting info on %s", full_path);
321 320
321 tlink = cifs_sb_tlink(cifs_sb);
322 if (IS_ERR(tlink))
323 return PTR_ERR(tlink);
324 tcon = tlink_tcon(tlink);
325
322 /* 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 */
323 rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data, 327 rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data,
324 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 328 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
325 CIFS_MOUNT_MAP_SPECIAL_CHR); 329 CIFS_MOUNT_MAP_SPECIAL_CHR);
330 cifs_put_tlink(tlink);
326 331
327 if (!rc) { 332 if (!rc) {
328 cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb); 333 cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
@@ -361,7 +366,8 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
361 int rc; 366 int rc;
362 int oplock = 0; 367 int oplock = 0;
363 __u16 netfid; 368 __u16 netfid;
364 struct cifsTconInfo *pTcon = cifs_sb_tcon(cifs_sb); 369 struct tcon_link *tlink;
370 struct cifsTconInfo *tcon;
365 char buf[24]; 371 char buf[24];
366 unsigned int bytes_read; 372 unsigned int bytes_read;
367 char *pbuf; 373 char *pbuf;
@@ -380,7 +386,12 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
380 return -EINVAL; /* EOPNOTSUPP? */ 386 return -EINVAL; /* EOPNOTSUPP? */
381 } 387 }
382 388
383 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,
384 CREATE_NOT_DIR, &netfid, &oplock, NULL, 395 CREATE_NOT_DIR, &netfid, &oplock, NULL,
385 cifs_sb->local_nls, 396 cifs_sb->local_nls,
386 cifs_sb->mnt_cifs_flags & 397 cifs_sb->mnt_cifs_flags &
@@ -388,7 +399,7 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
388 if (rc == 0) { 399 if (rc == 0) {
389 int buf_type = CIFS_NO_BUFFER; 400 int buf_type = CIFS_NO_BUFFER;
390 /* Read header */ 401 /* Read header */
391 rc = CIFSSMBRead(xid, pTcon, netfid, 402 rc = CIFSSMBRead(xid, tcon, netfid,
392 24 /* length */, 0 /* offset */, 403 24 /* length */, 0 /* offset */,
393 &bytes_read, &pbuf, &buf_type); 404 &bytes_read, &pbuf, &buf_type);
394 if ((rc == 0) && (bytes_read >= 8)) { 405 if ((rc == 0) && (bytes_read >= 8)) {
@@ -430,8 +441,9 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
430 fattr->cf_dtype = DT_REG; 441 fattr->cf_dtype = DT_REG;
431 rc = -EOPNOTSUPP; /* or some unknown SFU type */ 442 rc = -EOPNOTSUPP; /* or some unknown SFU type */
432 } 443 }
433 CIFSSMBClose(xid, pTcon, netfid); 444 CIFSSMBClose(xid, tcon, netfid);
434 } 445 }
446 cifs_put_tlink(tlink);
435 return rc; 447 return rc;
436} 448}
437 449
@@ -449,11 +461,19 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
449 ssize_t rc; 461 ssize_t rc;
450 char ea_value[4]; 462 char ea_value[4];
451 __u32 mode; 463 __u32 mode;
464 struct tcon_link *tlink;
465 struct cifsTconInfo *tcon;
452 466
453 rc = CIFSSMBQAllEAs(xid, cifs_sb_tcon(cifs_sb), 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",
454 ea_value, 4 /* size of buf */, cifs_sb->local_nls, 473 ea_value, 4 /* size of buf */, cifs_sb->local_nls,
455 cifs_sb->mnt_cifs_flags & 474 cifs_sb->mnt_cifs_flags &
456 CIFS_MOUNT_MAP_SPECIAL_CHR); 475 CIFS_MOUNT_MAP_SPECIAL_CHR);
476 cifs_put_tlink(tlink);
457 if (rc < 0) 477 if (rc < 0)
458 return (int)rc; 478 return (int)rc;
459 else if (rc > 3) { 479 else if (rc > 3) {
@@ -564,26 +584,33 @@ int cifs_get_inode_info(struct inode **pinode,
564{ 584{
565 int rc = 0, tmprc; 585 int rc = 0, tmprc;
566 struct cifsTconInfo *pTcon; 586 struct cifsTconInfo *pTcon;
587 struct tcon_link *tlink;
567 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 588 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
568 char *buf = NULL; 589 char *buf = NULL;
569 bool adjustTZ = false; 590 bool adjustTZ = false;
570 struct cifs_fattr fattr; 591 struct cifs_fattr fattr;
571 592
572 pTcon = cifs_sb_tcon(cifs_sb); 593 tlink = cifs_sb_tlink(cifs_sb);
594 if (IS_ERR(tlink))
595 return PTR_ERR(tlink);
596 pTcon = tlink_tcon(tlink);
597
573 cFYI(1, "Getting info on %s", full_path); 598 cFYI(1, "Getting info on %s", full_path);
574 599
575 if ((pfindData == NULL) && (*pinode != NULL)) { 600 if ((pfindData == NULL) && (*pinode != NULL)) {
576 if (CIFS_I(*pinode)->clientCanCacheRead) { 601 if (CIFS_I(*pinode)->clientCanCacheRead) {
577 cFYI(1, "No need to revalidate cached inode sizes"); 602 cFYI(1, "No need to revalidate cached inode sizes");
578 return rc; 603 goto cgii_exit;
579 } 604 }
580 } 605 }
581 606
582 /* if file info not passed in then get it from server */ 607 /* if file info not passed in then get it from server */
583 if (pfindData == NULL) { 608 if (pfindData == NULL) {
584 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); 609 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
585 if (buf == NULL) 610 if (buf == NULL) {
586 return -ENOMEM; 611 rc = -ENOMEM;
612 goto cgii_exit;
613 }
587 pfindData = (FILE_ALL_INFO *)buf; 614 pfindData = (FILE_ALL_INFO *)buf;
588 615
589 /* could do find first instead but this returns more info */ 616 /* could do find first instead but this returns more info */
@@ -688,6 +715,7 @@ int cifs_get_inode_info(struct inode **pinode,
688 715
689cgii_exit: 716cgii_exit:
690 kfree(buf); 717 kfree(buf);
718 cifs_put_tlink(tlink);
691 return rc; 719 return rc;
692} 720}
693 721
@@ -895,6 +923,7 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
895 struct cifsFileInfo *open_file; 923 struct cifsFileInfo *open_file;
896 struct cifsInodeInfo *cifsInode = CIFS_I(inode); 924 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
897 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 925 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
926 struct tcon_link *tlink = NULL;
898 struct cifsTconInfo *pTcon; 927 struct cifsTconInfo *pTcon;
899 FILE_BASIC_INFO info_buf; 928 FILE_BASIC_INFO info_buf;
900 929
@@ -942,7 +971,13 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
942 goto set_via_filehandle; 971 goto set_via_filehandle;
943 } 972 }
944 973
945 pTcon = cifs_sb_tcon(cifs_sb); 974 tlink = cifs_sb_tlink(cifs_sb);
975 if (IS_ERR(tlink)) {
976 rc = PTR_ERR(tlink);
977 tlink = NULL;
978 goto out;
979 }
980 pTcon = tlink_tcon(tlink);
946 981
947 /* 982 /*
948 * NT4 apparently returns success on this call, but it doesn't 983 * NT4 apparently returns success on this call, but it doesn't
@@ -987,6 +1022,8 @@ set_via_filehandle:
987 else 1022 else
988 cifsFileInfo_put(open_file); 1023 cifsFileInfo_put(open_file);
989out: 1024out:
1025 if (tlink != NULL)
1026 cifs_put_tlink(tlink);
990 return rc; 1027 return rc;
991} 1028}
992 1029
@@ -1004,10 +1041,16 @@ cifs_rename_pending_delete(char *full_path, struct dentry *dentry, int xid)
1004 struct inode *inode = dentry->d_inode; 1041 struct inode *inode = dentry->d_inode;
1005 struct cifsInodeInfo *cifsInode = CIFS_I(inode); 1042 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1006 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 1043 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1007 struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb); 1044 struct tcon_link *tlink;
1045 struct cifsTconInfo *tcon;
1008 __u32 dosattr, origattr; 1046 __u32 dosattr, origattr;
1009 FILE_BASIC_INFO *info_buf = NULL; 1047 FILE_BASIC_INFO *info_buf = NULL;
1010 1048
1049 tlink = cifs_sb_tlink(cifs_sb);
1050 if (IS_ERR(tlink))
1051 return PTR_ERR(tlink);
1052 tcon = tlink_tcon(tlink);
1053
1011 rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN, 1054 rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN,
1012 DELETE|FILE_WRITE_ATTRIBUTES, CREATE_NOT_DIR, 1055 DELETE|FILE_WRITE_ATTRIBUTES, CREATE_NOT_DIR,
1013 &netfid, &oplock, NULL, cifs_sb->local_nls, 1056 &netfid, &oplock, NULL, cifs_sb->local_nls,
@@ -1076,6 +1119,7 @@ out_close:
1076 CIFSSMBClose(xid, tcon, netfid); 1119 CIFSSMBClose(xid, tcon, netfid);
1077out: 1120out:
1078 kfree(info_buf); 1121 kfree(info_buf);
1122 cifs_put_tlink(tlink);
1079 return rc; 1123 return rc;
1080 1124
1081 /* 1125 /*
@@ -1115,12 +1159,18 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
1115 struct cifsInodeInfo *cifs_inode; 1159 struct cifsInodeInfo *cifs_inode;
1116 struct super_block *sb = dir->i_sb; 1160 struct super_block *sb = dir->i_sb;
1117 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 1161 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1118 struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb); 1162 struct tcon_link *tlink;
1163 struct cifsTconInfo *tcon;
1119 struct iattr *attrs = NULL; 1164 struct iattr *attrs = NULL;
1120 __u32 dosattr = 0, origattr = 0; 1165 __u32 dosattr = 0, origattr = 0;
1121 1166
1122 cFYI(1, "cifs_unlink, dir=0x%p, dentry=0x%p", dir, dentry); 1167 cFYI(1, "cifs_unlink, dir=0x%p, dentry=0x%p", dir, dentry);
1123 1168
1169 tlink = cifs_sb_tlink(cifs_sb);
1170 if (IS_ERR(tlink))
1171 return PTR_ERR(tlink);
1172 tcon = tlink_tcon(tlink);
1173
1124 xid = GetXid(); 1174 xid = GetXid();
1125 1175
1126 /* Unlink can be called from rename so we can not take the 1176 /* Unlink can be called from rename so we can not take the
@@ -1128,8 +1178,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
1128 full_path = build_path_from_dentry(dentry); 1178 full_path = build_path_from_dentry(dentry);
1129 if (full_path == NULL) { 1179 if (full_path == NULL) {
1130 rc = -ENOMEM; 1180 rc = -ENOMEM;
1131 FreeXid(xid); 1181 goto unlink_out;
1132 return rc;
1133 } 1182 }
1134 1183
1135 if ((tcon->ses->capabilities & CAP_UNIX) && 1184 if ((tcon->ses->capabilities & CAP_UNIX) &&
@@ -1195,10 +1244,11 @@ out_reval:
1195 dir->i_ctime = dir->i_mtime = current_fs_time(sb); 1244 dir->i_ctime = dir->i_mtime = current_fs_time(sb);
1196 cifs_inode = CIFS_I(dir); 1245 cifs_inode = CIFS_I(dir);
1197 CIFS_I(dir)->time = 0; /* force revalidate of dir as well */ 1246 CIFS_I(dir)->time = 0; /* force revalidate of dir as well */
1198 1247unlink_out:
1199 kfree(full_path); 1248 kfree(full_path);
1200 kfree(attrs); 1249 kfree(attrs);
1201 FreeXid(xid); 1250 FreeXid(xid);
1251 cifs_put_tlink(tlink);
1202 return rc; 1252 return rc;
1203} 1253}
1204 1254
@@ -1207,6 +1257,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
1207 int rc = 0, tmprc; 1257 int rc = 0, tmprc;
1208 int xid; 1258 int xid;
1209 struct cifs_sb_info *cifs_sb; 1259 struct cifs_sb_info *cifs_sb;
1260 struct tcon_link *tlink;
1210 struct cifsTconInfo *pTcon; 1261 struct cifsTconInfo *pTcon;
1211 char *full_path = NULL; 1262 char *full_path = NULL;
1212 struct inode *newinode = NULL; 1263 struct inode *newinode = NULL;
@@ -1214,16 +1265,18 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
1214 1265
1215 cFYI(1, "In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode); 1266 cFYI(1, "In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode);
1216 1267
1217 xid = GetXid();
1218
1219 cifs_sb = CIFS_SB(inode->i_sb); 1268 cifs_sb = CIFS_SB(inode->i_sb);
1220 pTcon = cifs_sb_tcon(cifs_sb); 1269 tlink = cifs_sb_tlink(cifs_sb);
1270 if (IS_ERR(tlink))
1271 return PTR_ERR(tlink);
1272 pTcon = tlink_tcon(tlink);
1273
1274 xid = GetXid();
1221 1275
1222 full_path = build_path_from_dentry(direntry); 1276 full_path = build_path_from_dentry(direntry);
1223 if (full_path == NULL) { 1277 if (full_path == NULL) {
1224 rc = -ENOMEM; 1278 rc = -ENOMEM;
1225 FreeXid(xid); 1279 goto mkdir_out;
1226 return rc;
1227 } 1280 }
1228 1281
1229 if ((pTcon->ses->capabilities & CAP_UNIX) && 1282 if ((pTcon->ses->capabilities & CAP_UNIX) &&
@@ -1381,6 +1434,7 @@ mkdir_get_info:
1381mkdir_out: 1434mkdir_out:
1382 kfree(full_path); 1435 kfree(full_path);
1383 FreeXid(xid); 1436 FreeXid(xid);
1437 cifs_put_tlink(tlink);
1384 return rc; 1438 return rc;
1385} 1439}
1386 1440
@@ -1389,6 +1443,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
1389 int rc = 0; 1443 int rc = 0;
1390 int xid; 1444 int xid;
1391 struct cifs_sb_info *cifs_sb; 1445 struct cifs_sb_info *cifs_sb;
1446 struct tcon_link *tlink;
1392 struct cifsTconInfo *pTcon; 1447 struct cifsTconInfo *pTcon;
1393 char *full_path = NULL; 1448 char *full_path = NULL;
1394 struct cifsInodeInfo *cifsInode; 1449 struct cifsInodeInfo *cifsInode;
@@ -1397,18 +1452,23 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
1397 1452
1398 xid = GetXid(); 1453 xid = GetXid();
1399 1454
1400 cifs_sb = CIFS_SB(inode->i_sb);
1401 pTcon = cifs_sb_tcon(cifs_sb);
1402
1403 full_path = build_path_from_dentry(direntry); 1455 full_path = build_path_from_dentry(direntry);
1404 if (full_path == NULL) { 1456 if (full_path == NULL) {
1405 rc = -ENOMEM; 1457 rc = -ENOMEM;
1406 FreeXid(xid); 1458 goto rmdir_exit;
1407 return rc; 1459 }
1460
1461 cifs_sb = CIFS_SB(inode->i_sb);
1462 tlink = cifs_sb_tlink(cifs_sb);
1463 if (IS_ERR(tlink)) {
1464 rc = PTR_ERR(tlink);
1465 goto rmdir_exit;
1408 } 1466 }
1467 pTcon = tlink_tcon(tlink);
1409 1468
1410 rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls, 1469 rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls,
1411 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 1470 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1471 cifs_put_tlink(tlink);
1412 1472
1413 if (!rc) { 1473 if (!rc) {
1414 drop_nlink(inode); 1474 drop_nlink(inode);
@@ -1429,6 +1489,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
1429 direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime = 1489 direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime =
1430 current_fs_time(inode->i_sb); 1490 current_fs_time(inode->i_sb);
1431 1491
1492rmdir_exit:
1432 kfree(full_path); 1493 kfree(full_path);
1433 FreeXid(xid); 1494 FreeXid(xid);
1434 return rc; 1495 return rc;
@@ -1439,10 +1500,16 @@ cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath,
1439 struct dentry *to_dentry, const char *toPath) 1500 struct dentry *to_dentry, const char *toPath)
1440{ 1501{
1441 struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb); 1502 struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb);
1442 struct cifsTconInfo *pTcon = cifs_sb_tcon(cifs_sb); 1503 struct tcon_link *tlink;
1504 struct cifsTconInfo *pTcon;
1443 __u16 srcfid; 1505 __u16 srcfid;
1444 int oplock, rc; 1506 int oplock, rc;
1445 1507
1508 tlink = cifs_sb_tlink(cifs_sb);
1509 if (IS_ERR(tlink))
1510 return PTR_ERR(tlink);
1511 pTcon = tlink_tcon(tlink);
1512
1446 /* try path-based rename first */ 1513 /* try path-based rename first */
1447 rc = CIFSSMBRename(xid, pTcon, fromPath, toPath, cifs_sb->local_nls, 1514 rc = CIFSSMBRename(xid, pTcon, fromPath, toPath, cifs_sb->local_nls,
1448 cifs_sb->mnt_cifs_flags & 1515 cifs_sb->mnt_cifs_flags &
@@ -1454,11 +1521,11 @@ cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath,
1454 * rename by filehandle to various Windows servers. 1521 * rename by filehandle to various Windows servers.
1455 */ 1522 */
1456 if (rc == 0 || rc != -ETXTBSY) 1523 if (rc == 0 || rc != -ETXTBSY)
1457 return rc; 1524 goto do_rename_exit;
1458 1525
1459 /* open-file renames don't work across directories */ 1526 /* open-file renames don't work across directories */
1460 if (to_dentry->d_parent != from_dentry->d_parent) 1527 if (to_dentry->d_parent != from_dentry->d_parent)
1461 return rc; 1528 goto do_rename_exit;
1462 1529
1463 /* open the file to be renamed -- we need DELETE perms */ 1530 /* open the file to be renamed -- we need DELETE perms */
1464 rc = CIFSSMBOpen(xid, pTcon, fromPath, FILE_OPEN, DELETE, 1531 rc = CIFSSMBOpen(xid, pTcon, fromPath, FILE_OPEN, DELETE,
@@ -1474,7 +1541,8 @@ cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath,
1474 1541
1475 CIFSSMBClose(xid, pTcon, srcfid); 1542 CIFSSMBClose(xid, pTcon, srcfid);
1476 } 1543 }
1477 1544do_rename_exit:
1545 cifs_put_tlink(tlink);
1478 return rc; 1546 return rc;
1479} 1547}
1480 1548
@@ -1484,13 +1552,17 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
1484 char *fromName = NULL; 1552 char *fromName = NULL;
1485 char *toName = NULL; 1553 char *toName = NULL;
1486 struct cifs_sb_info *cifs_sb; 1554 struct cifs_sb_info *cifs_sb;
1555 struct tcon_link *tlink;
1487 struct cifsTconInfo *tcon; 1556 struct cifsTconInfo *tcon;
1488 FILE_UNIX_BASIC_INFO *info_buf_source = NULL; 1557 FILE_UNIX_BASIC_INFO *info_buf_source = NULL;
1489 FILE_UNIX_BASIC_INFO *info_buf_target; 1558 FILE_UNIX_BASIC_INFO *info_buf_target;
1490 int xid, rc, tmprc; 1559 int xid, rc, tmprc;
1491 1560
1492 cifs_sb = CIFS_SB(source_dir->i_sb); 1561 cifs_sb = CIFS_SB(source_dir->i_sb);
1493 tcon = cifs_sb_tcon(cifs_sb); 1562 tlink = cifs_sb_tlink(cifs_sb);
1563 if (IS_ERR(tlink))
1564 return PTR_ERR(tlink);
1565 tcon = tlink_tcon(tlink);
1494 1566
1495 xid = GetXid(); 1567 xid = GetXid();
1496 1568
@@ -1566,6 +1638,7 @@ cifs_rename_exit:
1566 kfree(fromName); 1638 kfree(fromName);
1567 kfree(toName); 1639 kfree(toName);
1568 FreeXid(xid); 1640 FreeXid(xid);
1641 cifs_put_tlink(tlink);
1569 return rc; 1642 return rc;
1570} 1643}
1571 1644
@@ -1728,6 +1801,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1728 struct cifsFileInfo *open_file; 1801 struct cifsFileInfo *open_file;
1729 struct cifsInodeInfo *cifsInode = CIFS_I(inode); 1802 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1730 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 1803 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1804 struct tcon_link *tlink = NULL;
1731 struct cifsTconInfo *pTcon = NULL; 1805 struct cifsTconInfo *pTcon = NULL;
1732 1806
1733 /* 1807 /*
@@ -1758,8 +1832,12 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1758 rc = -EINVAL; 1832 rc = -EINVAL;
1759 1833
1760 if (rc != 0) { 1834 if (rc != 0) {
1761 if (pTcon == NULL) 1835 if (pTcon == NULL) {
1762 pTcon = cifs_sb_tcon(cifs_sb); 1836 tlink = cifs_sb_tlink(cifs_sb);
1837 if (IS_ERR(tlink))
1838 return PTR_ERR(tlink);
1839 pTcon = tlink_tcon(tlink);
1840 }
1763 1841
1764 /* Set file size by pathname rather than by handle 1842 /* Set file size by pathname rather than by handle
1765 either because no valid, writeable file handle for 1843 either because no valid, writeable file handle for
@@ -1790,6 +1868,8 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1790 CIFSSMBClose(xid, pTcon, netfid); 1868 CIFSSMBClose(xid, pTcon, netfid);
1791 } 1869 }
1792 } 1870 }
1871 if (tlink)
1872 cifs_put_tlink(tlink);
1793 } 1873 }
1794 1874
1795 if (rc == 0) { 1875 if (rc == 0) {
@@ -1810,6 +1890,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
1810 struct inode *inode = direntry->d_inode; 1890 struct inode *inode = direntry->d_inode;
1811 struct cifsInodeInfo *cifsInode = CIFS_I(inode); 1891 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1812 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 1892 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1893 struct tcon_link *tlink;
1813 struct cifsTconInfo *pTcon; 1894 struct cifsTconInfo *pTcon;
1814 struct cifs_unix_set_info_args *args = NULL; 1895 struct cifs_unix_set_info_args *args = NULL;
1815 struct cifsFileInfo *open_file; 1896 struct cifsFileInfo *open_file;
@@ -1905,11 +1986,17 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
1905 rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid); 1986 rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid);
1906 cifsFileInfo_put(open_file); 1987 cifsFileInfo_put(open_file);
1907 } else { 1988 } else {
1908 pTcon = cifs_sb_tcon(cifs_sb); 1989 tlink = cifs_sb_tlink(cifs_sb);
1990 if (IS_ERR(tlink)) {
1991 rc = PTR_ERR(tlink);
1992 goto out;
1993 }
1994 pTcon = tlink_tcon(tlink);
1909 rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args, 1995 rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args,
1910 cifs_sb->local_nls, 1996 cifs_sb->local_nls,
1911 cifs_sb->mnt_cifs_flags & 1997 cifs_sb->mnt_cifs_flags &
1912 CIFS_MOUNT_MAP_SPECIAL_CHR); 1998 CIFS_MOUNT_MAP_SPECIAL_CHR);
1999 cifs_put_tlink(tlink);
1913 } 2000 }
1914 2001
1915 if (rc) 2002 if (rc)
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 66db2d61fa43..b38fe6704ad2 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -249,7 +249,8 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr,
249 int rc; 249 int rc;
250 int oplock = 0; 250 int oplock = 0;
251 __u16 netfid = 0; 251 __u16 netfid = 0;
252 struct cifsTconInfo *pTcon = cifs_sb_tcon(cifs_sb); 252 struct tcon_link *tlink;
253 struct cifsTconInfo *pTcon;
253 u8 *buf; 254 u8 *buf;
254 char *pbuf; 255 char *pbuf;
255 unsigned int bytes_read = 0; 256 unsigned int bytes_read = 0;
@@ -261,23 +262,30 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr,
261 /* it's not a symlink */ 262 /* it's not a symlink */
262 return 0; 263 return 0;
263 264
265 tlink = cifs_sb_tlink(cifs_sb);
266 if (IS_ERR(tlink))
267 return PTR_ERR(tlink);
268 pTcon = tlink_tcon(tlink);
269
264 rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ, 270 rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ,
265 CREATE_NOT_DIR, &netfid, &oplock, &file_info, 271 CREATE_NOT_DIR, &netfid, &oplock, &file_info,
266 cifs_sb->local_nls, 272 cifs_sb->local_nls,
267 cifs_sb->mnt_cifs_flags & 273 cifs_sb->mnt_cifs_flags &
268 CIFS_MOUNT_MAP_SPECIAL_CHR); 274 CIFS_MOUNT_MAP_SPECIAL_CHR);
269 if (rc != 0) 275 if (rc != 0)
270 return rc; 276 goto out;
271 277
272 if (file_info.EndOfFile != CIFS_MF_SYMLINK_FILE_SIZE) { 278 if (file_info.EndOfFile != CIFS_MF_SYMLINK_FILE_SIZE) {
273 CIFSSMBClose(xid, pTcon, netfid); 279 CIFSSMBClose(xid, pTcon, netfid);
274 /* it's not a symlink */ 280 /* it's not a symlink */
275 return 0; 281 goto out;
276 } 282 }
277 283
278 buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL); 284 buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
279 if (!buf) 285 if (!buf) {
280 return -ENOMEM; 286 rc = -ENOMEM;
287 goto out;
288 }
281 pbuf = buf; 289 pbuf = buf;
282 290
283 rc = CIFSSMBRead(xid, pTcon, netfid, 291 rc = CIFSSMBRead(xid, pTcon, netfid,
@@ -287,23 +295,28 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr,
287 CIFSSMBClose(xid, pTcon, netfid); 295 CIFSSMBClose(xid, pTcon, netfid);
288 if (rc != 0) { 296 if (rc != 0) {
289 kfree(buf); 297 kfree(buf);
290 return rc; 298 goto out;
291 } 299 }
292 300
293 rc = CIFSParseMFSymlink(buf, bytes_read, &link_len, NULL); 301 rc = CIFSParseMFSymlink(buf, bytes_read, &link_len, NULL);
294 kfree(buf); 302 kfree(buf);
295 if (rc == -EINVAL) 303 if (rc == -EINVAL) {
296 /* it's not a symlink */ 304 /* it's not a symlink */
297 return 0; 305 rc = 0;
306 goto out;
307 }
308
298 if (rc != 0) 309 if (rc != 0)
299 return rc; 310 goto out;
300 311
301 /* it is a symlink */ 312 /* it is a symlink */
302 fattr->cf_eof = link_len; 313 fattr->cf_eof = link_len;
303 fattr->cf_mode &= ~S_IFMT; 314 fattr->cf_mode &= ~S_IFMT;
304 fattr->cf_mode |= S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO; 315 fattr->cf_mode |= S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO;
305 fattr->cf_dtype = DT_LNK; 316 fattr->cf_dtype = DT_LNK;
306 return 0; 317out:
318 cifs_put_tlink(tlink);
319 return rc;
307} 320}
308 321
309int 322int
@@ -314,17 +327,17 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
314 int xid; 327 int xid;
315 char *fromName = NULL; 328 char *fromName = NULL;
316 char *toName = NULL; 329 char *toName = NULL;
317 struct cifs_sb_info *cifs_sb_target; 330 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
331 struct tcon_link *tlink;
318 struct cifsTconInfo *pTcon; 332 struct cifsTconInfo *pTcon;
319 struct cifsInodeInfo *cifsInode; 333 struct cifsInodeInfo *cifsInode;
320 334
321 xid = GetXid(); 335 tlink = cifs_sb_tlink(cifs_sb);
322 336 if (IS_ERR(tlink))
323 cifs_sb_target = CIFS_SB(inode->i_sb); 337 return PTR_ERR(tlink);
324 pTcon = cifs_sb_tcon(cifs_sb_target); 338 pTcon = tlink_tcon(tlink);
325 339
326/* No need to check for cross device links since server will do that 340 xid = GetXid();
327 BB note DFS case in future though (when we may have to check) */
328 341
329 fromName = build_path_from_dentry(old_file); 342 fromName = build_path_from_dentry(old_file);
330 toName = build_path_from_dentry(direntry); 343 toName = build_path_from_dentry(direntry);
@@ -336,13 +349,13 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
336/* if (cifs_sb_target->tcon->ses->capabilities & CAP_UNIX)*/ 349/* if (cifs_sb_target->tcon->ses->capabilities & CAP_UNIX)*/
337 if (pTcon->unix_ext) 350 if (pTcon->unix_ext)
338 rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName, 351 rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName,
339 cifs_sb_target->local_nls, 352 cifs_sb->local_nls,
340 cifs_sb_target->mnt_cifs_flags & 353 cifs_sb->mnt_cifs_flags &
341 CIFS_MOUNT_MAP_SPECIAL_CHR); 354 CIFS_MOUNT_MAP_SPECIAL_CHR);
342 else { 355 else {
343 rc = CIFSCreateHardLink(xid, pTcon, fromName, toName, 356 rc = CIFSCreateHardLink(xid, pTcon, fromName, toName,
344 cifs_sb_target->local_nls, 357 cifs_sb->local_nls,
345 cifs_sb_target->mnt_cifs_flags & 358 cifs_sb->mnt_cifs_flags &
346 CIFS_MOUNT_MAP_SPECIAL_CHR); 359 CIFS_MOUNT_MAP_SPECIAL_CHR);
347 if ((rc == -EIO) || (rc == -EINVAL)) 360 if ((rc == -EIO) || (rc == -EINVAL))
348 rc = -EOPNOTSUPP; 361 rc = -EOPNOTSUPP;
@@ -378,6 +391,7 @@ cifs_hl_exit:
378 kfree(fromName); 391 kfree(fromName);
379 kfree(toName); 392 kfree(toName);
380 FreeXid(xid); 393 FreeXid(xid);
394 cifs_put_tlink(tlink);
381 return rc; 395 return rc;
382} 396}
383 397
@@ -390,10 +404,19 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
390 char *full_path = NULL; 404 char *full_path = NULL;
391 char *target_path = NULL; 405 char *target_path = NULL;
392 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 406 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
393 struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb); 407 struct tcon_link *tlink = NULL;
408 struct cifsTconInfo *tcon;
394 409
395 xid = GetXid(); 410 xid = GetXid();
396 411
412 tlink = cifs_sb_tlink(cifs_sb);
413 if (IS_ERR(tlink)) {
414 rc = PTR_ERR(tlink);
415 tlink = NULL;
416 goto out;
417 }
418 tcon = tlink_tcon(tlink);
419
397 /* 420 /*
398 * For now, we just handle symlinks with unix extensions enabled. 421 * For now, we just handle symlinks with unix extensions enabled.
399 * Eventually we should handle NTFS reparse points, and MacOS 422 * Eventually we should handle NTFS reparse points, and MacOS
@@ -442,6 +465,8 @@ out:
442 } 465 }
443 466
444 FreeXid(xid); 467 FreeXid(xid);
468 if (tlink)
469 cifs_put_tlink(tlink);
445 nd_set_link(nd, target_path); 470 nd_set_link(nd, target_path);
446 return NULL; 471 return NULL;
447} 472}
@@ -451,22 +476,25 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
451{ 476{
452 int rc = -EOPNOTSUPP; 477 int rc = -EOPNOTSUPP;
453 int xid; 478 int xid;
454 struct cifs_sb_info *cifs_sb; 479 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
480 struct tcon_link *tlink;
455 struct cifsTconInfo *pTcon; 481 struct cifsTconInfo *pTcon;
456 char *full_path = NULL; 482 char *full_path = NULL;
457 struct inode *newinode = NULL; 483 struct inode *newinode = NULL;
458 484
459 xid = GetXid(); 485 xid = GetXid();
460 486
461 cifs_sb = CIFS_SB(inode->i_sb); 487 tlink = cifs_sb_tlink(cifs_sb);
462 pTcon = cifs_sb_tcon(cifs_sb); 488 if (IS_ERR(tlink)) {
489 rc = PTR_ERR(tlink);
490 goto symlink_exit;
491 }
492 pTcon = tlink_tcon(tlink);
463 493
464 full_path = build_path_from_dentry(direntry); 494 full_path = build_path_from_dentry(direntry);
465
466 if (full_path == NULL) { 495 if (full_path == NULL) {
467 rc = -ENOMEM; 496 rc = -ENOMEM;
468 FreeXid(xid); 497 goto symlink_exit;
469 return rc;
470 } 498 }
471 499
472 cFYI(1, "Full path: %s", full_path); 500 cFYI(1, "Full path: %s", full_path);
@@ -504,8 +532,9 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
504 d_instantiate(direntry, newinode); 532 d_instantiate(direntry, newinode);
505 } 533 }
506 } 534 }
507 535symlink_exit:
508 kfree(full_path); 536 kfree(full_path);
537 cifs_put_tlink(tlink);
509 FreeXid(xid); 538 FreeXid(xid);
510 return rc; 539 return rc;
511} 540}
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 887a7e230376..170047cf4522 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -223,33 +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 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 232 tlink = cifs_sb_tlink(cifs_sb);
232 if (cifs_sb == NULL) 233 if (IS_ERR(tlink))
233 return -EINVAL; 234 return PTR_ERR(tlink);
235 pTcon = tlink_tcon(tlink);
234 236
235 if (file->private_data == NULL) 237 if (file->private_data == NULL)
236 file->private_data = 238 file->private_data =
237 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;
243 }
238 244
239 if (file->private_data == NULL)
240 return -ENOMEM;
241 cifsFile = file->private_data; 245 cifsFile = file->private_data;
242 cifsFile->invalidHandle = true; 246 cifsFile->invalidHandle = true;
243 cifsFile->srch_inf.endOfSearch = false; 247 cifsFile->srch_inf.endOfSearch = false;
244 cifsFile->tcon = cifs_sb_tcon(cifs_sb); 248 cifsFile->tcon = pTcon;
245 pTcon = cifsFile->tcon;
246 if (pTcon == NULL)
247 return -EINVAL;
248 249
249 full_path = build_path_from_dentry(file->f_path.dentry); 250 full_path = build_path_from_dentry(file->f_path.dentry);
250 251 if (full_path == NULL) {
251 if (full_path == NULL) 252 rc = -ENOMEM;
252 return -ENOMEM; 253 goto error_exit;
254 }
253 255
254 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);
255 257
@@ -282,7 +284,9 @@ ffirst_retry:
282 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM; 284 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
283 goto ffirst_retry; 285 goto ffirst_retry;
284 } 286 }
287error_exit:
285 kfree(full_path); 288 kfree(full_path);
289 cifs_put_tlink(tlink);
286 return rc; 290 return rc;
287} 291}
288 292
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
index 41f95bf67977..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(cifs_sb); 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(cifs_sb); 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(cifs_sb); 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(cifs_sb);
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}