[CIFS] Add support for TCP_NODELAY
authorSteve French <sfrench@us.ibm.com>
Fri, 1 Jan 2010 01:28:43 +0000 (01:28 +0000)
committerSteve French <sfrench@us.ibm.com>
Fri, 1 Jan 2010 01:28:43 +0000 (01:28 +0000)
mount option sockopt=TCP_NODELAY helpful for faster networks
boosting performance.  Kernel bugzilla bug number 14032.

Signed-off-by: Steve French <sfrench@us.ibm.com>
fs/cifs/CHANGES
fs/cifs/cifsfs.h
fs/cifs/cifsglob.h
fs/cifs/connect.c

index 7b2600b..49503d2 100644 (file)
@@ -1,3 +1,7 @@
+Version 1.62
+------------
+Add sockopt=TCP_NODELAY mount option.
+
 Version 1.61
 ------------
 Fix append problem to Samba servers (files opened with O_APPEND could
index ac2b24c..78c1b86 100644 (file)
@@ -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;
 #endif /* EXPERIMENTAL */
 
-#define CIFS_VERSION   "1.61"
+#define CIFS_VERSION   "1.62"
 #endif                         /* _CIFSFS_H */
index 4b35f7e..ed751bb 100644 (file)
@@ -149,6 +149,7 @@ struct TCP_Server_Info {
        bool svlocal:1;                 /* local server or remote */
        bool noblocksnd;                /* use blocking sendmsg */
        bool noautotune;                /* do not autotune send buf sizes */
+       bool tcp_nodelay;
        atomic_t inFlight;  /* number of requests on the wire to server */
 #ifdef CONFIG_CIFS_STATS2
        atomic_t inSend; /* requests trying to send */
index 3bbcaa7..2e9e09c 100644 (file)
@@ -98,7 +98,7 @@ struct smb_vol {
        bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
        unsigned int rsize;
        unsigned int wsize;
-       unsigned int sockopt;
+       bool sockopt_tcp_nodelay:1;
        unsigned short int port;
        char *prepath;
 };
@@ -1142,9 +1142,11 @@ cifs_parse_mount_options(char *options, const char *devname,
                                        simple_strtoul(value, &value, 0);
                        }
                } else if (strnicmp(data, "sockopt", 5) == 0) {
-                       if (value && *value) {
-                               vol->sockopt =
-                                       simple_strtoul(value, &value, 0);
+                       if (!value || !*value) {
+                               cERROR(1, ("no socket option specified"));
+                               continue;
+                       } else if (strnicmp(value, "TCP_NODELAY", 11) == 0) {
+                               vol->sockopt_tcp_nodelay = 1;
                        }
                } else if (strnicmp(data, "netbiosname", 4) == 0) {
                        if (!value || !*value || (*value == ' ')) {
@@ -1514,6 +1516,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
 
        tcp_ses->noblocksnd = volume_info->noblocksnd;
        tcp_ses->noautotune = volume_info->noautotune;
+       tcp_ses->tcp_nodelay = volume_info->sockopt_tcp_nodelay;
        atomic_set(&tcp_ses->inFlight, 0);
        init_waitqueue_head(&tcp_ses->response_q);
        init_waitqueue_head(&tcp_ses->request_q);
@@ -1764,6 +1767,7 @@ static int
 ipv4_connect(struct TCP_Server_Info *server)
 {
        int rc = 0;
+       int val;
        bool connected = false;
        __be16 orig_port = 0;
        struct socket *socket = server->ssocket;
@@ -1845,6 +1849,14 @@ ipv4_connect(struct TCP_Server_Info *server)
                        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",
                 socket->sk->sk_sndbuf,
                 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo));
@@ -1916,6 +1928,7 @@ static int
 ipv6_connect(struct TCP_Server_Info *server)
 {
        int rc = 0;
+       int val;
        bool connected = false;
        __be16 orig_port = 0;
        struct socket *socket = server->ssocket;
@@ -1987,6 +2000,15 @@ ipv6_connect(struct TCP_Server_Info *server)
         */
        socket->sk->sk_rcvtimeo = 7 * 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;
 
        return rc;