aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/cifsglob.h11
-rw-r--r--fs/cifs/cifsproto.h5
-rw-r--r--fs/cifs/cifssmb.c97
-rw-r--r--fs/cifs/connect.c9
-rw-r--r--fs/cifs/file.c14
-rw-r--r--fs/cifs/sess.c2
-rw-r--r--fs/cifs/transport.c91
7 files changed, 133 insertions, 96 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 87f51f23276f..4ff8179df7ec 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -471,6 +471,17 @@ struct dir_notify_req {
471#define CIFS_LARGE_BUFFER 2 471#define CIFS_LARGE_BUFFER 2
472#define CIFS_IOVEC 4 /* array of response buffers */ 472#define CIFS_IOVEC 4 /* array of response buffers */
473 473
474/* Type of Request to SendReceive2 */
475#define CIFS_STD_OP 0 /* normal request timeout */
476#define CIFS_LONG_OP 1 /* long op (up to 45 sec, oplock time) */
477#define CIFS_VLONG_OP 2 /* sloow op - can take up to 180 seconds */
478#define CIFS_BLOCKING_OP 4 /* operation can block */
479#define CIFS_ASYNC_OP 8 /* do not wait for response */
480#define CIFS_TIMEOUT_MASK 0x00F /* only one of 5 above set in req */
481#define CIFS_LOG_ERROR 0x010 /* log NT STATUS if non-zero */
482#define CIFS_LARGE_BUF_OP 0x020 /* large request buffer */
483#define CIFS_NO_RESP 0x040 /* no response buffer required */
484
474/* Security Flags: indicate type of session setup needed */ 485/* Security Flags: indicate type of session setup needed */
475#define CIFSSEC_MAY_SIGN 0x00001 486#define CIFSSEC_MAY_SIGN 0x00001
476#define CIFSSEC_MAY_NTLM 0x00002 487#define CIFSSEC_MAY_NTLM 0x00002
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index dd1d7c200ee6..0c55dff2add8 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -48,10 +48,11 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *,
48 struct smb_hdr * /* input */ , 48 struct smb_hdr * /* input */ ,
49 struct smb_hdr * /* out */ , 49 struct smb_hdr * /* out */ ,
50 int * /* bytes returned */ , const int long_op); 50 int * /* bytes returned */ , const int long_op);
51extern int SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,
52 struct smb_hdr *in_buf, int flags);
51extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *, 53extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *,
52 struct kvec *, int /* nvec to send */, 54 struct kvec *, int /* nvec to send */,
53 int * /* type of buf returned */ , const int long_op, 55 int * /* type of buf returned */ , const int flags);
54 const int logError /* whether to log status code*/ );
55extern int SendReceiveBlockingLock(const unsigned int /* xid */ , 56extern int SendReceiveBlockingLock(const unsigned int /* xid */ ,
56 struct cifsTconInfo *, 57 struct cifsTconInfo *,
57 struct smb_hdr * /* input */ , 58 struct smb_hdr * /* input */ ,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 59d7b7c037ad..9e8a6bef029a 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -698,9 +698,7 @@ int
698CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon) 698CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
699{ 699{
700 struct smb_hdr *smb_buffer; 700 struct smb_hdr *smb_buffer;
701 struct smb_hdr *smb_buffer_response; /* BB removeme BB */
702 int rc = 0; 701 int rc = 0;
703 int length;
704 702
705 cFYI(1, ("In tree disconnect")); 703 cFYI(1, ("In tree disconnect"));
706 /* 704 /*
@@ -737,16 +735,12 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
737 if (rc) { 735 if (rc) {
738 up(&tcon->tconSem); 736 up(&tcon->tconSem);
739 return rc; 737 return rc;
740 } else {
741 smb_buffer_response = smb_buffer; /* BB removeme BB */
742 } 738 }
743 rc = SendReceive(xid, tcon->ses, smb_buffer, smb_buffer_response, 739
744 &length, 0); 740 rc = SendReceiveNoRsp(xid, tcon->ses, smb_buffer, 0);
745 if (rc) 741 if (rc)
746 cFYI(1, ("Tree disconnect failed %d", rc)); 742 cFYI(1, ("Tree disconnect failed %d", rc));
747 743
748 if (smb_buffer)
749 cifs_small_buf_release(smb_buffer);
750 up(&tcon->tconSem); 744 up(&tcon->tconSem);
751 745
752 /* No need to return error on this operation if tid invalidated and 746 /* No need to return error on this operation if tid invalidated and
@@ -760,10 +754,8 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
760int 754int
761CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses) 755CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
762{ 756{
763 struct smb_hdr *smb_buffer_response;
764 LOGOFF_ANDX_REQ *pSMB; 757 LOGOFF_ANDX_REQ *pSMB;
765 int rc = 0; 758 int rc = 0;
766 int length;
767 759
768 cFYI(1, ("In SMBLogoff for session disconnect")); 760 cFYI(1, ("In SMBLogoff for session disconnect"));
769 if (ses) 761 if (ses)
@@ -782,8 +774,6 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
782 return rc; 774 return rc;
783 } 775 }
784 776
785 smb_buffer_response = (struct smb_hdr *)pSMB; /* BB removeme BB */
786
787 if (ses->server) { 777 if (ses->server) {
788 pSMB->hdr.Mid = GetNextMid(ses->server); 778 pSMB->hdr.Mid = GetNextMid(ses->server);
789 779
@@ -795,8 +785,7 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
795 pSMB->hdr.Uid = ses->Suid; 785 pSMB->hdr.Uid = ses->Suid;
796 786
797 pSMB->AndXCommand = 0xFF; 787 pSMB->AndXCommand = 0xFF;
798 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, 788 rc = SendReceiveNoRsp(xid, ses, (struct smb_hdr *) pSMB, 0);
799 smb_buffer_response, &length, 0);
800 if (ses->server) { 789 if (ses->server) {
801 atomic_dec(&ses->server->socketUseCount); 790 atomic_dec(&ses->server->socketUseCount);
802 if (atomic_read(&ses->server->socketUseCount) == 0) { 791 if (atomic_read(&ses->server->socketUseCount) == 0) {
@@ -807,7 +796,6 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
807 } 796 }
808 } 797 }
809 up(&ses->sesSem); 798 up(&ses->sesSem);
810 cifs_small_buf_release(pSMB);
811 799
812 /* if session dead then we do not need to do ulogoff, 800 /* if session dead then we do not need to do ulogoff,
813 since server closed smb session, no sense reporting 801 since server closed smb session, no sense reporting
@@ -1255,7 +1243,7 @@ OldOpenRetry:
1255 pSMB->ByteCount = cpu_to_le16(count); 1243 pSMB->ByteCount = cpu_to_le16(count);
1256 /* long_op set to 1 to allow for oplock break timeouts */ 1244 /* long_op set to 1 to allow for oplock break timeouts */
1257 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1245 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1258 (struct smb_hdr *) pSMBr, &bytes_returned, 1); 1246 (struct smb_hdr *)pSMBr, &bytes_returned, CIFS_LONG_OP);
1259 cifs_stats_inc(&tcon->num_opens); 1247 cifs_stats_inc(&tcon->num_opens);
1260 if (rc) { 1248 if (rc) {
1261 cFYI(1, ("Error in Open = %d", rc)); 1249 cFYI(1, ("Error in Open = %d", rc));
@@ -1368,7 +1356,7 @@ openRetry:
1368 pSMB->ByteCount = cpu_to_le16(count); 1356 pSMB->ByteCount = cpu_to_le16(count);
1369 /* long_op set to 1 to allow for oplock break timeouts */ 1357 /* long_op set to 1 to allow for oplock break timeouts */
1370 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1358 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1371 (struct smb_hdr *) pSMBr, &bytes_returned, 1); 1359 (struct smb_hdr *)pSMBr, &bytes_returned, CIFS_LONG_OP);
1372 cifs_stats_inc(&tcon->num_opens); 1360 cifs_stats_inc(&tcon->num_opens);
1373 if (rc) { 1361 if (rc) {
1374 cFYI(1, ("Error in Open = %d", rc)); 1362 cFYI(1, ("Error in Open = %d", rc));
@@ -1446,7 +1434,7 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
1446 iov[0].iov_base = (char *)pSMB; 1434 iov[0].iov_base = (char *)pSMB;
1447 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; 1435 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
1448 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */, 1436 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
1449 &resp_buf_type, 0 /* not long op */, 1 /* log err */ ); 1437 &resp_buf_type, CIFS_STD_OP | CIFS_LOG_ERROR);
1450 cifs_stats_inc(&tcon->num_reads); 1438 cifs_stats_inc(&tcon->num_reads);
1451 pSMBr = (READ_RSP *)iov[0].iov_base; 1439 pSMBr = (READ_RSP *)iov[0].iov_base;
1452 if (rc) { 1440 if (rc) {
@@ -1665,7 +1653,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1665 1653
1666 1654
1667 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 1655 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type,
1668 long_op, 0 /* do not log STATUS code */ ); 1656 long_op);
1669 cifs_stats_inc(&tcon->num_writes); 1657 cifs_stats_inc(&tcon->num_writes);
1670 if (rc) { 1658 if (rc) {
1671 cFYI(1, ("Send error Write2 = %d", rc)); 1659 cFYI(1, ("Send error Write2 = %d", rc));
@@ -1707,7 +1695,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1707 int timeout = 0; 1695 int timeout = 0;
1708 __u16 count; 1696 __u16 count;
1709 1697
1710 cFYI(1, ("In CIFSSMBLock - timeout %d numLock %d", waitFlag, numLock)); 1698 cFYI(1, ("CIFSSMBLock timeout %d numLock %d", waitFlag, numLock));
1711 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB); 1699 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
1712 1700
1713 if (rc) 1701 if (rc)
@@ -1716,10 +1704,10 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1716 pSMBr = (LOCK_RSP *)pSMB; /* BB removeme BB */ 1704 pSMBr = (LOCK_RSP *)pSMB; /* BB removeme BB */
1717 1705
1718 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) { 1706 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
1719 timeout = -1; /* no response expected */ 1707 timeout = CIFS_ASYNC_OP; /* no response expected */
1720 pSMB->Timeout = 0; 1708 pSMB->Timeout = 0;
1721 } else if (waitFlag == TRUE) { 1709 } else if (waitFlag == TRUE) {
1722 timeout = 3; /* blocking operation, no timeout */ 1710 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
1723 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */ 1711 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
1724 } else { 1712 } else {
1725 pSMB->Timeout = 0; 1713 pSMB->Timeout = 0;
@@ -1749,15 +1737,16 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1749 if (waitFlag) { 1737 if (waitFlag) {
1750 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, 1738 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
1751 (struct smb_hdr *) pSMBr, &bytes_returned); 1739 (struct smb_hdr *) pSMBr, &bytes_returned);
1740 cifs_small_buf_release(pSMB);
1752 } else { 1741 } else {
1753 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1742 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *)pSMB,
1754 (struct smb_hdr *) pSMBr, &bytes_returned, timeout); 1743 timeout);
1744 /* SMB buffer freed by function above */
1755 } 1745 }
1756 cifs_stats_inc(&tcon->num_locks); 1746 cifs_stats_inc(&tcon->num_locks);
1757 if (rc) { 1747 if (rc) {
1758 cFYI(1, ("Send error in Lock = %d", rc)); 1748 cFYI(1, ("Send error in Lock = %d", rc));
1759 } 1749 }
1760 cifs_small_buf_release(pSMB);
1761 1750
1762 /* Note: On -EAGAIN error only caller can retry on handle based calls 1751 /* Note: On -EAGAIN error only caller can retry on handle based calls
1763 since file handle passed in no longer valid */ 1752 since file handle passed in no longer valid */
@@ -1776,7 +1765,9 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1776 int rc = 0; 1765 int rc = 0;
1777 int timeout = 0; 1766 int timeout = 0;
1778 int bytes_returned = 0; 1767 int bytes_returned = 0;
1768 int resp_buf_type = 0;
1779 __u16 params, param_offset, offset, byte_count, count; 1769 __u16 params, param_offset, offset, byte_count, count;
1770 struct kvec iov[1];
1780 1771
1781 cFYI(1, ("Posix Lock")); 1772 cFYI(1, ("Posix Lock"));
1782 1773
@@ -1818,7 +1809,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1818 1809
1819 parm_data->lock_type = cpu_to_le16(lock_type); 1810 parm_data->lock_type = cpu_to_le16(lock_type);
1820 if (waitFlag) { 1811 if (waitFlag) {
1821 timeout = 3; /* blocking operation, no timeout */ 1812 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
1822 parm_data->lock_flags = cpu_to_le16(1); 1813 parm_data->lock_flags = cpu_to_le16(1);
1823 pSMB->Timeout = cpu_to_le32(-1); 1814 pSMB->Timeout = cpu_to_le32(-1);
1824 } else 1815 } else
@@ -1838,8 +1829,13 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1838 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, 1829 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
1839 (struct smb_hdr *) pSMBr, &bytes_returned); 1830 (struct smb_hdr *) pSMBr, &bytes_returned);
1840 } else { 1831 } else {
1841 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1832 iov[0].iov_base = (char *)pSMB;
1842 (struct smb_hdr *) pSMBr, &bytes_returned, timeout); 1833 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
1834 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
1835 &resp_buf_type, timeout);
1836 pSMB = NULL; /* request buf already freed by SendReceive2. Do
1837 not try to free it twice below on exit */
1838 pSMBr = (struct smb_com_transaction2_sfi_rsp *)iov[0].iov_base;
1843 } 1839 }
1844 1840
1845 if (rc) { 1841 if (rc) {
@@ -1874,6 +1870,11 @@ plk_err_exit:
1874 if (pSMB) 1870 if (pSMB)
1875 cifs_small_buf_release(pSMB); 1871 cifs_small_buf_release(pSMB);
1876 1872
1873 if (resp_buf_type == CIFS_SMALL_BUFFER)
1874 cifs_small_buf_release(iov[0].iov_base);
1875 else if (resp_buf_type == CIFS_LARGE_BUFFER)
1876 cifs_buf_release(iov[0].iov_base);
1877
1877 /* Note: On -EAGAIN error only caller can retry on handle based calls 1878 /* Note: On -EAGAIN error only caller can retry on handle based calls
1878 since file handle passed in no longer valid */ 1879 since file handle passed in no longer valid */
1879 1880
@@ -1886,8 +1887,6 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
1886{ 1887{
1887 int rc = 0; 1888 int rc = 0;
1888 CLOSE_REQ *pSMB = NULL; 1889 CLOSE_REQ *pSMB = NULL;
1889 CLOSE_RSP *pSMBr = NULL;
1890 int bytes_returned;
1891 cFYI(1, ("In CIFSSMBClose")); 1890 cFYI(1, ("In CIFSSMBClose"));
1892 1891
1893/* do not retry on dead session on close */ 1892/* do not retry on dead session on close */
@@ -1897,13 +1896,10 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
1897 if (rc) 1896 if (rc)
1898 return rc; 1897 return rc;
1899 1898
1900 pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */
1901
1902 pSMB->FileID = (__u16) smb_file_id; 1899 pSMB->FileID = (__u16) smb_file_id;
1903 pSMB->LastWriteTime = 0xFFFFFFFF; 1900 pSMB->LastWriteTime = 0xFFFFFFFF;
1904 pSMB->ByteCount = 0; 1901 pSMB->ByteCount = 0;
1905 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1902 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
1906 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1907 cifs_stats_inc(&tcon->num_closes); 1903 cifs_stats_inc(&tcon->num_closes);
1908 if (rc) { 1904 if (rc) {
1909 if (rc != -EINTR) { 1905 if (rc != -EINTR) {
@@ -1912,8 +1908,6 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
1912 } 1908 }
1913 } 1909 }
1914 1910
1915 cifs_small_buf_release(pSMB);
1916
1917 /* Since session is dead, file will be closed on server already */ 1911 /* Since session is dead, file will be closed on server already */
1918 if (rc == -EAGAIN) 1912 if (rc == -EAGAIN)
1919 rc = 0; 1913 rc = 0;
@@ -3102,7 +3096,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
3102 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; 3096 iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
3103 3097
3104 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, 3098 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
3105 0 /* not long op */, 0 /* do not log STATUS codes */ ); 3099 CIFS_STD_OP);
3106 cifs_stats_inc(&tcon->num_acl_get); 3100 cifs_stats_inc(&tcon->num_acl_get);
3107 if (rc) { 3101 if (rc) {
3108 cFYI(1, ("Send error in QuerySecDesc = %d", rc)); 3102 cFYI(1, ("Send error in QuerySecDesc = %d", rc));
@@ -3763,8 +3757,6 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon,
3763{ 3757{
3764 int rc = 0; 3758 int rc = 0;
3765 FINDCLOSE_REQ *pSMB = NULL; 3759 FINDCLOSE_REQ *pSMB = NULL;
3766 CLOSE_RSP *pSMBr = NULL; /* BB removeme BB */
3767 int bytes_returned;
3768 3760
3769 cFYI(1, ("In CIFSSMBFindClose")); 3761 cFYI(1, ("In CIFSSMBFindClose"));
3770 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB); 3762 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
@@ -3776,16 +3768,13 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon,
3776 if (rc) 3768 if (rc)
3777 return rc; 3769 return rc;
3778 3770
3779 pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */
3780 pSMB->FileID = searchHandle; 3771 pSMB->FileID = searchHandle;
3781 pSMB->ByteCount = 0; 3772 pSMB->ByteCount = 0;
3782 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3773 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
3783 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3784 if (rc) { 3774 if (rc) {
3785 cERROR(1, ("Send error in FindClose = %d", rc)); 3775 cERROR(1, ("Send error in FindClose = %d", rc));
3786 } 3776 }
3787 cifs_stats_inc(&tcon->num_fclose); 3777 cifs_stats_inc(&tcon->num_fclose);
3788 cifs_small_buf_release(pSMB);
3789 3778
3790 /* Since session is dead, search handle closed on server already */ 3779 /* Since session is dead, search handle closed on server already */
3791 if (rc == -EAGAIN) 3780 if (rc == -EAGAIN)
@@ -4707,11 +4696,9 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
4707 __u16 fid, __u32 pid_of_opener, int SetAllocation) 4696 __u16 fid, __u32 pid_of_opener, int SetAllocation)
4708{ 4697{
4709 struct smb_com_transaction2_sfi_req *pSMB = NULL; 4698 struct smb_com_transaction2_sfi_req *pSMB = NULL;
4710 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
4711 char *data_offset; 4699 char *data_offset;
4712 struct file_end_of_file_info *parm_data; 4700 struct file_end_of_file_info *parm_data;
4713 int rc = 0; 4701 int rc = 0;
4714 int bytes_returned = 0;
4715 __u16 params, param_offset, offset, byte_count, count; 4702 __u16 params, param_offset, offset, byte_count, count;
4716 4703
4717 cFYI(1, ("SetFileSize (via SetFileInfo) %lld", 4704 cFYI(1, ("SetFileSize (via SetFileInfo) %lld",
@@ -4721,8 +4708,6 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
4721 if (rc) 4708 if (rc)
4722 return rc; 4709 return rc;
4723 4710
4724 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
4725
4726 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); 4711 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
4727 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); 4712 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
4728 4713
@@ -4773,17 +4758,13 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
4773 pSMB->Reserved4 = 0; 4758 pSMB->Reserved4 = 0;
4774 pSMB->hdr.smb_buf_length += byte_count; 4759 pSMB->hdr.smb_buf_length += byte_count;
4775 pSMB->ByteCount = cpu_to_le16(byte_count); 4760 pSMB->ByteCount = cpu_to_le16(byte_count);
4776 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4761 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
4777 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4778 if (rc) { 4762 if (rc) {
4779 cFYI(1, 4763 cFYI(1,
4780 ("Send error in SetFileInfo (SetFileSize) = %d", 4764 ("Send error in SetFileInfo (SetFileSize) = %d",
4781 rc)); 4765 rc));
4782 } 4766 }
4783 4767
4784 if (pSMB)
4785 cifs_small_buf_release(pSMB);
4786
4787 /* Note: On -EAGAIN error only caller can retry on handle based calls 4768 /* Note: On -EAGAIN error only caller can retry on handle based calls
4788 since file handle passed in no longer valid */ 4769 since file handle passed in no longer valid */
4789 4770
@@ -4801,10 +4782,8 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon,
4801 const FILE_BASIC_INFO *data, __u16 fid) 4782 const FILE_BASIC_INFO *data, __u16 fid)
4802{ 4783{
4803 struct smb_com_transaction2_sfi_req *pSMB = NULL; 4784 struct smb_com_transaction2_sfi_req *pSMB = NULL;
4804 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
4805 char *data_offset; 4785 char *data_offset;
4806 int rc = 0; 4786 int rc = 0;
4807 int bytes_returned = 0;
4808 __u16 params, param_offset, offset, byte_count, count; 4787 __u16 params, param_offset, offset, byte_count, count;
4809 4788
4810 cFYI(1, ("Set Times (via SetFileInfo)")); 4789 cFYI(1, ("Set Times (via SetFileInfo)"));
@@ -4813,8 +4792,6 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon,
4813 if (rc) 4792 if (rc)
4814 return rc; 4793 return rc;
4815 4794
4816 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
4817
4818 /* At this point there is no need to override the current pid 4795 /* At this point there is no need to override the current pid
4819 with the pid of the opener, but that could change if we someday 4796 with the pid of the opener, but that could change if we someday
4820 use an existing handle (rather than opening one on the fly) */ 4797 use an existing handle (rather than opening one on the fly) */
@@ -4854,14 +4831,11 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon,
4854 pSMB->hdr.smb_buf_length += byte_count; 4831 pSMB->hdr.smb_buf_length += byte_count;
4855 pSMB->ByteCount = cpu_to_le16(byte_count); 4832 pSMB->ByteCount = cpu_to_le16(byte_count);
4856 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); 4833 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
4857 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4834 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
4858 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
4859 if (rc) { 4835 if (rc) {
4860 cFYI(1, ("Send error in Set Time (SetFileInfo) = %d", rc)); 4836 cFYI(1, ("Send error in Set Time (SetFileInfo) = %d", rc));
4861 } 4837 }
4862 4838
4863 cifs_small_buf_release(pSMB);
4864
4865 /* Note: On -EAGAIN error only caller can retry on handle based calls 4839 /* Note: On -EAGAIN error only caller can retry on handle based calls
4866 since file handle passed in no longer valid */ 4840 since file handle passed in no longer valid */
4867 4841
@@ -5152,7 +5126,8 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
5152 pSMB->ByteCount = 0; 5126 pSMB->ByteCount = 0;
5153 5127
5154 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5128 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
5155 (struct smb_hdr *) pSMBr, &bytes_returned, -1); 5129 (struct smb_hdr *)pSMBr, &bytes_returned,
5130 CIFS_ASYNC_OP);
5156 if (rc) { 5131 if (rc) {
5157 cFYI(1, ("Error in Notify = %d", rc)); 5132 cFYI(1, ("Error in Notify = %d", rc));
5158 } else { 5133 } else {
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index c52a76ff4bb9..26e1087e081f 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2374,7 +2374,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2374 pSMB->req_no_secext.ByteCount = cpu_to_le16(count); 2374 pSMB->req_no_secext.ByteCount = cpu_to_le16(count);
2375 2375
2376 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, 2376 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2377 &bytes_returned, 1); 2377 &bytes_returned, CIFS_LONG_OP);
2378 if (rc) { 2378 if (rc) {
2379/* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */ 2379/* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */
2380 } else if ((smb_buffer_response->WordCount == 3) 2380 } else if ((smb_buffer_response->WordCount == 3)
@@ -2678,7 +2678,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2678 pSMB->req.ByteCount = cpu_to_le16(count); 2678 pSMB->req.ByteCount = cpu_to_le16(count);
2679 2679
2680 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, 2680 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2681 &bytes_returned, 1); 2681 &bytes_returned, CIFS_LONG_OP);
2682 2682
2683 if (smb_buffer_response->Status.CifsError == 2683 if (smb_buffer_response->Status.CifsError ==
2684 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED)) 2684 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
@@ -3105,7 +3105,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3105 pSMB->req.ByteCount = cpu_to_le16(count); 3105 pSMB->req.ByteCount = cpu_to_le16(count);
3106 3106
3107 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, 3107 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
3108 &bytes_returned, 1); 3108 &bytes_returned, CIFS_LONG_OP);
3109 if (rc) { 3109 if (rc) {
3110/* rc = map_smb_to_linux_error(smb_buffer_response) done in SendReceive now */ 3110/* rc = map_smb_to_linux_error(smb_buffer_response) done in SendReceive now */
3111 } else if ((smb_buffer_response->WordCount == 3) || 3111 } else if ((smb_buffer_response->WordCount == 3) ||
@@ -3381,7 +3381,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3381 pSMB->hdr.smb_buf_length += count; 3381 pSMB->hdr.smb_buf_length += count;
3382 pSMB->ByteCount = cpu_to_le16(count); 3382 pSMB->ByteCount = cpu_to_le16(count);
3383 3383
3384 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length, 0); 3384 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
3385 CIFS_STD_OP);
3385 3386
3386 /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */ 3387 /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
3387 /* above now done in SendReceive */ 3388 /* above now done in SendReceive */
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 68ad4ca0cfa3..82326d2142e7 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -835,9 +835,9 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
835 xid = GetXid(); 835 xid = GetXid();
836 836
837 if (*poffset > file->f_path.dentry->d_inode->i_size) 837 if (*poffset > file->f_path.dentry->d_inode->i_size)
838 long_op = 2; /* writes past end of file can take a long time */ 838 long_op = CIFS_VLONG_OP; /* writes past EOF take long time */
839 else 839 else
840 long_op = 1; 840 long_op = CIFS_LONG_OP;
841 841
842 for (total_written = 0; write_size > total_written; 842 for (total_written = 0; write_size > total_written;
843 total_written += bytes_written) { 843 total_written += bytes_written) {
@@ -884,7 +884,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
884 } 884 }
885 } else 885 } else
886 *poffset += bytes_written; 886 *poffset += bytes_written;
887 long_op = FALSE; /* subsequent writes fast - 887 long_op = CIFS_STD_OP; /* subsequent writes fast -
888 15 seconds is plenty */ 888 15 seconds is plenty */
889 } 889 }
890 890
@@ -934,9 +934,9 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
934 xid = GetXid(); 934 xid = GetXid();
935 935
936 if (*poffset > file->f_path.dentry->d_inode->i_size) 936 if (*poffset > file->f_path.dentry->d_inode->i_size)
937 long_op = 2; /* writes past end of file can take a long time */ 937 long_op = CIFS_VLONG_OP; /* writes past EOF can be slow */
938 else 938 else
939 long_op = 1; 939 long_op = CIFS_LONG_OP;
940 940
941 for (total_written = 0; write_size > total_written; 941 for (total_written = 0; write_size > total_written;
942 total_written += bytes_written) { 942 total_written += bytes_written) {
@@ -1002,7 +1002,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
1002 } 1002 }
1003 } else 1003 } else
1004 *poffset += bytes_written; 1004 *poffset += bytes_written;
1005 long_op = FALSE; /* subsequent writes fast - 1005 long_op = CIFS_STD_OP; /* subsequent writes fast -
1006 15 seconds is plenty */ 1006 15 seconds is plenty */
1007 } 1007 }
1008 1008
@@ -1360,7 +1360,7 @@ retry:
1360 open_file->netfid, 1360 open_file->netfid,
1361 bytes_to_write, offset, 1361 bytes_to_write, offset,
1362 &bytes_written, iov, n_iov, 1362 &bytes_written, iov, n_iov,
1363 1); 1363 CIFS_LONG_OP);
1364 atomic_dec(&open_file->wrtPending); 1364 atomic_dec(&open_file->wrtPending);
1365 if (rc || bytes_written < bytes_to_write) { 1365 if (rc || bytes_written < bytes_to_write) {
1366 cERROR(1, ("Write2 ret %d, wrote %d", 1366 cERROR(1, ("Write2 ret %d, wrote %d",
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 899dc6078d9a..ed01ef382aa9 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -514,7 +514,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
514 iov[1].iov_base = str_area; 514 iov[1].iov_base = str_area;
515 iov[1].iov_len = count; 515 iov[1].iov_len = count;
516 rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, 516 rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type,
517 0 /* not long op */, 1 /* log NT STATUS if any */ ); 517 CIFS_STD_OP /* not long */ | CIFS_LOG_ERROR);
518 /* SMB request buf freed in SendReceive2 */ 518 /* SMB request buf freed in SendReceive2 */
519 519
520 cFYI(1, ("ssetup rc from sendrecv2 is %d", rc)); 520 cFYI(1, ("ssetup rc from sendrecv2 is %d", rc));
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 7ed32b3cb781..50b623ad9320 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -308,7 +308,7 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
308 308
309static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op) 309static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op)
310{ 310{
311 if (long_op == -1) { 311 if (long_op == CIFS_ASYNC_OP) {
312 /* oplock breaks must not be held up */ 312 /* oplock breaks must not be held up */
313 atomic_inc(&ses->server->inFlight); 313 atomic_inc(&ses->server->inFlight);
314 } else { 314 } else {
@@ -337,7 +337,7 @@ static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op)
337 as they are allowed to block on server */ 337 as they are allowed to block on server */
338 338
339 /* update # of requests on the wire to server */ 339 /* update # of requests on the wire to server */
340 if (long_op < 3) 340 if (long_op != CIFS_BLOCKING_OP)
341 atomic_inc(&ses->server->inFlight); 341 atomic_inc(&ses->server->inFlight);
342 spin_unlock(&GlobalMid_Lock); 342 spin_unlock(&GlobalMid_Lock);
343 break; 343 break;
@@ -415,17 +415,48 @@ static int wait_for_response(struct cifsSesInfo *ses,
415 } 415 }
416} 416}
417 417
418
419/*
420 *
421 * Send an SMB Request. No response info (other than return code)
422 * needs to be parsed.
423 *
424 * flags indicate the type of request buffer and how long to wait
425 * and whether to log NT STATUS code (error) before mapping it to POSIX error
426 *
427 */
428int
429SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,
430 struct smb_hdr *in_buf, int flags)
431{
432 int rc;
433 struct kvec iov[1];
434 int resp_buf_type;
435
436 iov[0].iov_base = (char *)in_buf;
437 iov[0].iov_len = in_buf->smb_buf_length + 4;
438 flags |= CIFS_NO_RESP;
439 rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags);
440#ifdef CONFIG_CIFS_DEBUG2
441 cFYI(1, ("SendRcvNoR flags %d rc %d", flags, rc));
442#endif
443 return rc;
444}
445
418int 446int
419SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, 447SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
420 struct kvec *iov, int n_vec, int *pRespBufType /* ret */, 448 struct kvec *iov, int n_vec, int *pRespBufType /* ret */,
421 const int long_op, const int logError) 449 const int flags)
422{ 450{
423 int rc = 0; 451 int rc = 0;
452 int long_op;
424 unsigned int receive_len; 453 unsigned int receive_len;
425 unsigned long timeout; 454 unsigned long timeout;
426 struct mid_q_entry *midQ; 455 struct mid_q_entry *midQ;
427 struct smb_hdr *in_buf = iov[0].iov_base; 456 struct smb_hdr *in_buf = iov[0].iov_base;
428 457
458 long_op = flags & CIFS_TIMEOUT_MASK;
459
429 *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */ 460 *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */
430 461
431 if ((ses == NULL) || (ses->server == NULL)) { 462 if ((ses == NULL) || (ses->server == NULL)) {
@@ -483,15 +514,22 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
483 if (rc < 0) 514 if (rc < 0)
484 goto out; 515 goto out;
485 516
486 if (long_op == -1) 517 if (long_op == CIFS_STD_OP)
487 goto out; 518 timeout = 15 * HZ;
488 else if (long_op == 2) /* writes past end of file can take loong time */ 519 else if (long_op == CIFS_VLONG_OP) /* e.g. slow writes past EOF */
489 timeout = 180 * HZ; 520 timeout = 180 * HZ;
490 else if (long_op == 1) 521 else if (long_op == CIFS_LONG_OP)
491 timeout = 45 * HZ; /* should be greater than 522 timeout = 45 * HZ; /* should be greater than
492 servers oplock break timeout (about 43 seconds) */ 523 servers oplock break timeout (about 43 seconds) */
493 else 524 else if (long_op == CIFS_ASYNC_OP)
494 timeout = 15 * HZ; 525 goto out;
526 else if (long_op == CIFS_BLOCKING_OP)
527 timeout = 0x7FFFFFFF; /* large, but not so large as to wrap */
528 else {
529 cERROR(1, ("unknown timeout flag %d", long_op));
530 rc = -EIO;
531 goto out;
532 }
495 533
496 /* wait for 15 seconds or until woken up due to response arriving or 534 /* wait for 15 seconds or until woken up due to response arriving or
497 due to last connection to this server being unmounted */ 535 due to last connection to this server being unmounted */
@@ -566,7 +604,8 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
566 } 604 }
567 605
568 /* BB special case reconnect tid and uid here? */ 606 /* BB special case reconnect tid and uid here? */
569 rc = map_smb_to_linux_error(midQ->resp_buf, logError); 607 rc = map_smb_to_linux_error(midQ->resp_buf,
608 flags & CIFS_LOG_ERROR);
570 609
571 /* convert ByteCount if necessary */ 610 /* convert ByteCount if necessary */
572 if (receive_len >= sizeof(struct smb_hdr) - 4 611 if (receive_len >= sizeof(struct smb_hdr) - 4
@@ -574,8 +613,10 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
574 (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ ) 613 (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ )
575 BCC(midQ->resp_buf) = 614 BCC(midQ->resp_buf) =
576 le16_to_cpu(BCC_LE(midQ->resp_buf)); 615 le16_to_cpu(BCC_LE(midQ->resp_buf));
577 midQ->resp_buf = NULL; /* mark it so will not be freed 616 if ((flags & CIFS_NO_RESP) == 0)
578 by DeleteMidQEntry */ 617 midQ->resp_buf = NULL; /* mark it so buf will
618 not be freed by
619 DeleteMidQEntry */
579 } else { 620 } else {
580 rc = -EIO; 621 rc = -EIO;
581 cFYI(1, ("Bad MID state?")); 622 cFYI(1, ("Bad MID state?"));
@@ -663,17 +704,25 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
663 if (rc < 0) 704 if (rc < 0)
664 goto out; 705 goto out;
665 706
666 if (long_op == -1) 707 if (long_op == CIFS_STD_OP)
708 timeout = 15 * HZ;
709 /* wait for 15 seconds or until woken up due to response arriving or
710 due to last connection to this server being unmounted */
711 else if (long_op == CIFS_ASYNC_OP)
667 goto out; 712 goto out;
668 else if (long_op == 2) /* writes past end of file can take loong time */ 713 else if (long_op == CIFS_VLONG_OP) /* writes past EOF can be slow */
669 timeout = 180 * HZ; 714 timeout = 180 * HZ;
670 else if (long_op == 1) 715 else if (long_op == CIFS_LONG_OP)
671 timeout = 45 * HZ; /* should be greater than 716 timeout = 45 * HZ; /* should be greater than
672 servers oplock break timeout (about 43 seconds) */ 717 servers oplock break timeout (about 43 seconds) */
673 else 718 else if (long_op == CIFS_BLOCKING_OP)
674 timeout = 15 * HZ; 719 timeout = 0x7FFFFFFF; /* large but no so large as to wrap */
675 /* wait for 15 seconds or until woken up due to response arriving or 720 else {
676 due to last connection to this server being unmounted */ 721 cERROR(1, ("unknown timeout flag %d", long_op));
722 rc = -EIO;
723 goto out;
724 }
725
677 if (signal_pending(current)) { 726 if (signal_pending(current)) {
678 /* if signal pending do not hold up user for full smb timeout 727 /* if signal pending do not hold up user for full smb timeout
679 but we still give response a chance to complete */ 728 but we still give response a chance to complete */
@@ -812,7 +861,7 @@ send_lock_cancel(const unsigned int xid, struct cifsTconInfo *tcon,
812 pSMB->hdr.Mid = GetNextMid(ses->server); 861 pSMB->hdr.Mid = GetNextMid(ses->server);
813 862
814 return SendReceive(xid, ses, in_buf, out_buf, 863 return SendReceive(xid, ses, in_buf, out_buf,
815 &bytes_returned, 0); 864 &bytes_returned, CIFS_STD_OP);
816} 865}
817 866
818int 867int
@@ -844,7 +893,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
844 to the same server. We may make this configurable later or 893 to the same server. We may make this configurable later or
845 use ses->maxReq */ 894 use ses->maxReq */
846 895
847 rc = wait_for_free_request(ses, 3); 896 rc = wait_for_free_request(ses, CIFS_BLOCKING_OP);
848 if (rc) 897 if (rc)
849 return rc; 898 return rc;
850 899