CIFS: Introduce credit-based flow control

and send no more than credits value requests at once. For SMB/CIFS
it's trivial: increment this value by receiving any message and
decrement by sending one.

Reviewed-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru>
Signed-off-by: Steve French <sfrench@us.ibm.com>
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index fb78bc9..d55de96 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -250,8 +250,9 @@
 	bool noblocksnd;		/* use blocking sendmsg */
 	bool noautotune;		/* do not autotune send buf sizes */
 	bool tcp_nodelay;
+	int credits;  /* send no more requests at once */
 	unsigned int in_flight;  /* number of requests on the wire to server */
-	spinlock_t req_lock; /* protect the value above */
+	spinlock_t req_lock;  /* protect the two values above */
 	struct mutex srv_mutex;
 	struct task_struct *tsk;
 	char server_GUID[16];
@@ -314,12 +315,14 @@
 	return num;
 }
 
-static inline void
-dec_in_flight(struct TCP_Server_Info *server)
+static inline bool
+has_credits(struct TCP_Server_Info *server)
 {
+	int num;
 	spin_lock(&server->req_lock);
-	server->in_flight--;
+	num = server->credits;
 	spin_unlock(&server->req_lock);
+	return num > 0;
 }
 
 /*