Commit 6a5fa236 authored by Steve French's avatar Steve French

[CIFS] Add support for TCP_NODELAY

mount option sockopt=TCP_NODELAY helpful for faster networks
boosting performance.  Kernel bugzilla bug number 14032.
Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent df9d1e8a
Version 1.62
------------
Add sockopt=TCP_NODELAY mount option.
Version 1.61 Version 1.61
------------ ------------
Fix append problem to Samba servers (files opened with O_APPEND could Fix append problem to Samba servers (files opened with O_APPEND could
......
...@@ -113,5 +113,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); ...@@ -113,5 +113,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
extern const struct export_operations cifs_export_ops; extern const struct export_operations cifs_export_ops;
#endif /* EXPERIMENTAL */ #endif /* EXPERIMENTAL */
#define CIFS_VERSION "1.61" #define CIFS_VERSION "1.62"
#endif /* _CIFSFS_H */ #endif /* _CIFSFS_H */
...@@ -149,6 +149,7 @@ struct TCP_Server_Info { ...@@ -149,6 +149,7 @@ struct TCP_Server_Info {
bool svlocal:1; /* local server or remote */ bool svlocal:1; /* local server or remote */
bool noblocksnd; /* use blocking sendmsg */ bool noblocksnd; /* use blocking sendmsg */
bool noautotune; /* do not autotune send buf sizes */ bool noautotune; /* do not autotune send buf sizes */
bool tcp_nodelay;
atomic_t inFlight; /* number of requests on the wire to server */ atomic_t inFlight; /* number of requests on the wire to server */
#ifdef CONFIG_CIFS_STATS2 #ifdef CONFIG_CIFS_STATS2
atomic_t inSend; /* requests trying to send */ atomic_t inSend; /* requests trying to send */
......
...@@ -98,7 +98,7 @@ struct smb_vol { ...@@ -98,7 +98,7 @@ struct smb_vol {
bool nostrictsync:1; /* do not force expensive SMBflush on every sync */ bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
unsigned int rsize; unsigned int rsize;
unsigned int wsize; unsigned int wsize;
unsigned int sockopt; bool sockopt_tcp_nodelay:1;
unsigned short int port; unsigned short int port;
char *prepath; char *prepath;
}; };
...@@ -1142,9 +1142,11 @@ cifs_parse_mount_options(char *options, const char *devname, ...@@ -1142,9 +1142,11 @@ cifs_parse_mount_options(char *options, const char *devname,
simple_strtoul(value, &value, 0); simple_strtoul(value, &value, 0);
} }
} else if (strnicmp(data, "sockopt", 5) == 0) { } else if (strnicmp(data, "sockopt", 5) == 0) {
if (value && *value) { if (!value || !*value) {
vol->sockopt = cERROR(1, ("no socket option specified"));
simple_strtoul(value, &value, 0); continue;
} else if (strnicmp(value, "TCP_NODELAY", 11) == 0) {
vol->sockopt_tcp_nodelay = 1;
} }
} else if (strnicmp(data, "netbiosname", 4) == 0) { } else if (strnicmp(data, "netbiosname", 4) == 0) {
if (!value || !*value || (*value == ' ')) { if (!value || !*value || (*value == ' ')) {
...@@ -1514,6 +1516,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info) ...@@ -1514,6 +1516,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
tcp_ses->noblocksnd = volume_info->noblocksnd; tcp_ses->noblocksnd = volume_info->noblocksnd;
tcp_ses->noautotune = volume_info->noautotune; tcp_ses->noautotune = volume_info->noautotune;
tcp_ses->tcp_nodelay = volume_info->sockopt_tcp_nodelay;
atomic_set(&tcp_ses->inFlight, 0); atomic_set(&tcp_ses->inFlight, 0);
init_waitqueue_head(&tcp_ses->response_q); init_waitqueue_head(&tcp_ses->response_q);
init_waitqueue_head(&tcp_ses->request_q); init_waitqueue_head(&tcp_ses->request_q);
...@@ -1764,6 +1767,7 @@ static int ...@@ -1764,6 +1767,7 @@ static int
ipv4_connect(struct TCP_Server_Info *server) ipv4_connect(struct TCP_Server_Info *server)
{ {
int rc = 0; int rc = 0;
int val;
bool connected = false; bool connected = false;
__be16 orig_port = 0; __be16 orig_port = 0;
struct socket *socket = server->ssocket; struct socket *socket = server->ssocket;
...@@ -1845,6 +1849,14 @@ ipv4_connect(struct TCP_Server_Info *server) ...@@ -1845,6 +1849,14 @@ ipv4_connect(struct TCP_Server_Info *server)
socket->sk->sk_rcvbuf = 140 * 1024; socket->sk->sk_rcvbuf = 140 * 1024;
} }
if (server->tcp_nodelay) {
val = 1;
rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
(char *)&val, sizeof(val));
if (rc)
cFYI(1, ("set TCP_NODELAY socket option error %d", rc));
}
cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx", cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
socket->sk->sk_sndbuf, socket->sk->sk_sndbuf,
socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo)); socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo));
...@@ -1916,6 +1928,7 @@ static int ...@@ -1916,6 +1928,7 @@ static int
ipv6_connect(struct TCP_Server_Info *server) ipv6_connect(struct TCP_Server_Info *server)
{ {
int rc = 0; int rc = 0;
int val;
bool connected = false; bool connected = false;
__be16 orig_port = 0; __be16 orig_port = 0;
struct socket *socket = server->ssocket; struct socket *socket = server->ssocket;
...@@ -1987,6 +2000,15 @@ ipv6_connect(struct TCP_Server_Info *server) ...@@ -1987,6 +2000,15 @@ ipv6_connect(struct TCP_Server_Info *server)
*/ */
socket->sk->sk_rcvtimeo = 7 * HZ; socket->sk->sk_rcvtimeo = 7 * HZ;
socket->sk->sk_sndtimeo = 5 * HZ; socket->sk->sk_sndtimeo = 5 * HZ;
if (server->tcp_nodelay) {
val = 1;
rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
(char *)&val, sizeof(val));
if (rc)
cFYI(1, ("set TCP_NODELAY socket option error %d", rc));
}
server->ssocket = socket; server->ssocket = socket;
return rc; return rc;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment