aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/inode.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2010-10-30 04:43:08 -0400
committerIngo Molnar <mingo@elte.hu>2010-10-30 04:43:08 -0400
commit169ed55bd30305b933f52bfab32a58671d44ab68 (patch)
tree32e280957474f458901abfce16fa2a1687ef7497 /fs/cifs/inode.c
parent3d7851b3cdd43a734e5cc4c643fd886ab28ad4d5 (diff)
parent45f81b1c96d9793e47ce925d257ea693ce0b193e (diff)
Merge branch 'tip/perf/jump-label-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace into perf/urgent
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r--fs/cifs/inode.c237
1 files changed, 184 insertions, 53 deletions
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);