diff options
| author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2016-06-02 09:54:12 +0200 | 
|---|---|---|
| committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2016-06-02 09:54:12 +0200 | 
| commit | 5599617ec0719dba3b1f85a4abca2a6c93368ae3 (patch) | |
| tree | 7d2f9bb6a538ee8ed5cfa391f2cfa72a3e2daa9f /fs/cifs/connect.c | |
| parent | 8d19d7d9dbc25d1a1ffa602ed9eff25a88c98163 (diff) | |
| parent | 66fd7a66e8b9e11e49f46ea77910f935c4dee5c3 (diff) | |
Merge remote-tracking branch 'airlied/drm-next' into drm-intel-next-queued
Git got absolutely destroyed with all our cherry-picking from
drm-intel-next-queued to various branches. It ended up inserting
intel_crtc_page_flip 2x even in intel_display.c.
Backmerge to get back to sanity.
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Diffstat (limited to 'fs/cifs/connect.c')
| -rw-r--r-- | fs/cifs/connect.c | 139 | 
1 files changed, 43 insertions, 96 deletions
| diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 6f62ac821a84..66736f57b5ab 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -501,99 +501,34 @@ server_unresponsive(struct TCP_Server_Info *server)  	return false;  } -/* - * kvec_array_init - clone a kvec array, and advance into it - * @new:	pointer to memory for cloned array - * @iov:	pointer to original array - * @nr_segs:	number of members in original array - * @bytes:	number of bytes to advance into the cloned array - * - * This function will copy the array provided in iov to a section of memory - * and advance the specified number of bytes into the new array. It returns - * the number of segments in the new array. "new" must be at least as big as - * the original iov array. - */ -static unsigned int -kvec_array_init(struct kvec *new, struct kvec *iov, unsigned int nr_segs, -		size_t bytes) -{ -	size_t base = 0; - -	while (bytes || !iov->iov_len) { -		int copy = min(bytes, iov->iov_len); - -		bytes -= copy; -		base += copy; -		if (iov->iov_len == base) { -			iov++; -			nr_segs--; -			base = 0; -		} -	} -	memcpy(new, iov, sizeof(*iov) * nr_segs); -	new->iov_base += base; -	new->iov_len -= base; -	return nr_segs; -} - -static struct kvec * -get_server_iovec(struct TCP_Server_Info *server, unsigned int nr_segs) -{ -	struct kvec *new_iov; - -	if (server->iov && nr_segs <= server->nr_iov) -		return server->iov; - -	/* not big enough -- allocate a new one and release the old */ -	new_iov = kmalloc(sizeof(*new_iov) * nr_segs, GFP_NOFS); -	if (new_iov) { -		kfree(server->iov); -		server->iov = new_iov; -		server->nr_iov = nr_segs; -	} -	return new_iov; -} - -int -cifs_readv_from_socket(struct TCP_Server_Info *server, struct kvec *iov_orig, -		       unsigned int nr_segs, unsigned int to_read) +static int +cifs_readv_from_socket(struct TCP_Server_Info *server, struct msghdr *smb_msg)  {  	int length = 0;  	int total_read; -	unsigned int segs; -	struct msghdr smb_msg; -	struct kvec *iov; -	iov = get_server_iovec(server, nr_segs); -	if (!iov) -		return -ENOMEM; - -	smb_msg.msg_control = NULL; -	smb_msg.msg_controllen = 0; +	smb_msg->msg_control = NULL; +	smb_msg->msg_controllen = 0; -	for (total_read = 0; to_read; total_read += length, to_read -= length) { +	for (total_read = 0; msg_data_left(smb_msg); total_read += length) {  		try_to_freeze(); -		if (server_unresponsive(server)) { -			total_read = -ECONNABORTED; -			break; -		} +		if (server_unresponsive(server)) +			return -ECONNABORTED; -		segs = kvec_array_init(iov, iov_orig, nr_segs, total_read); +		length = sock_recvmsg(server->ssocket, smb_msg, 0); -		length = kernel_recvmsg(server->ssocket, &smb_msg, -					iov, segs, to_read, 0); +		if (server->tcpStatus == CifsExiting) +			return -ESHUTDOWN; -		if (server->tcpStatus == CifsExiting) { -			total_read = -ESHUTDOWN; -			break; -		} else if (server->tcpStatus == CifsNeedReconnect) { +		if (server->tcpStatus == CifsNeedReconnect) {  			cifs_reconnect(server); -			total_read = -ECONNABORTED; -			break; -		} else if (length == -ERESTARTSYS || -			   length == -EAGAIN || -			   length == -EINTR) { +			return -ECONNABORTED; +		} + +		if (length == -ERESTARTSYS || +		    length == -EAGAIN || +		    length == -EINTR) {  			/*  			 * Minimum sleep to prevent looping, allowing socket  			 * to clear and app threads to set tcpStatus @@ -602,12 +537,12 @@ cifs_readv_from_socket(struct TCP_Server_Info *server, struct kvec *iov_orig,  			usleep_range(1000, 2000);  			length = 0;  			continue; -		} else if (length <= 0) { -			cifs_dbg(FYI, "Received no data or error: expecting %d\n" -				 "got %d", to_read, length); +		} + +		if (length <= 0) { +			cifs_dbg(FYI, "Received no data or error: %d\n", length);  			cifs_reconnect(server); -			total_read = -ECONNABORTED; -			break; +			return -ECONNABORTED;  		}  	}  	return total_read; @@ -617,12 +552,21 @@ int  cifs_read_from_socket(struct TCP_Server_Info *server, char *buf,  		      unsigned int to_read)  { -	struct kvec iov; +	struct msghdr smb_msg; +	struct kvec iov = {.iov_base = buf, .iov_len = to_read}; +	iov_iter_kvec(&smb_msg.msg_iter, READ | ITER_KVEC, &iov, 1, to_read); -	iov.iov_base = buf; -	iov.iov_len = to_read; +	return cifs_readv_from_socket(server, &smb_msg); +} -	return cifs_readv_from_socket(server, &iov, 1, to_read); +int +cifs_read_page_from_socket(struct TCP_Server_Info *server, struct page *page, +		      unsigned int to_read) +{ +	struct msghdr smb_msg; +	struct bio_vec bv = {.bv_page = page, .bv_len = to_read}; +	iov_iter_bvec(&smb_msg.msg_iter, READ | ITER_BVEC, &bv, 1, to_read); +	return cifs_readv_from_socket(server, &smb_msg);  }  static bool @@ -783,7 +727,6 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server)  	}  	kfree(server->hostname); -	kfree(server->iov);  	kfree(server);  	length = atomic_dec_return(&tcpSesAllocCount); @@ -1196,8 +1139,12 @@ cifs_parse_devname(const char *devname, struct smb_vol *vol)  	convert_delimiter(vol->UNC, '\\'); -	/* If pos is NULL, or is a bogus trailing delimiter then no prepath */ -	if (!*pos++ || !*pos) +	/* skip any delimiter */ +	if (*pos == '/' || *pos == '\\') +		pos++; + +	/* If pos is NULL then no prepath */ +	if (!*pos)  		return 0;  	vol->prepath = kstrdup(pos, GFP_KERNEL); @@ -2918,7 +2865,7 @@ static inline void  cifs_reclassify_socket4(struct socket *sock)  {  	struct sock *sk = sock->sk; -	BUG_ON(sock_owned_by_user(sk)); +	BUG_ON(!sock_allow_reclassification(sk));  	sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS",  		&cifs_slock_key[0], "sk_lock-AF_INET-CIFS", &cifs_key[0]);  } @@ -2927,7 +2874,7 @@ static inline void  cifs_reclassify_socket6(struct socket *sock)  {  	struct sock *sk = sock->sk; -	BUG_ON(sock_owned_by_user(sk)); +	BUG_ON(!sock_allow_reclassification(sk));  	sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS",  		&cifs_slock_key[1], "sk_lock-AF_INET6-CIFS", &cifs_key[1]);  } | 
