diff options
Diffstat (limited to 'fs/cifs/misc.c')
| -rw-r--r-- | fs/cifs/misc.c | 31 | 
1 files changed, 27 insertions, 4 deletions
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 460084a8eac5..53e8362cbc4a 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -82,6 +82,7 @@ sesInfoAlloc(void)  		INIT_LIST_HEAD(&ret_buf->smb_ses_list);  		INIT_LIST_HEAD(&ret_buf->tcon_list);  		mutex_init(&ret_buf->session_mutex); +		spin_lock_init(&ret_buf->iface_lock);  	}  	return ret_buf;  } @@ -102,6 +103,7 @@ sesInfoFree(struct cifs_ses *buf_to_free)  	kfree(buf_to_free->user_name);  	kfree(buf_to_free->domainName);  	kzfree(buf_to_free->auth_key.response); +	kfree(buf_to_free->iface_list);  	kzfree(buf_to_free);  } @@ -117,6 +119,9 @@ tconInfoAlloc(void)  		INIT_LIST_HEAD(&ret_buf->openFileList);  		INIT_LIST_HEAD(&ret_buf->tcon_list);  		spin_lock_init(&ret_buf->open_file_lock); +		mutex_init(&ret_buf->crfid.fid_mutex); +		ret_buf->crfid.fid = kzalloc(sizeof(struct cifs_fid), +					     GFP_KERNEL);  #ifdef CONFIG_CIFS_STATS  		spin_lock_init(&ret_buf->stat_lock);  #endif @@ -134,6 +139,7 @@ tconInfoFree(struct cifs_tcon *buf_to_free)  	atomic_dec(&tconInfoAllocCount);  	kfree(buf_to_free->nativeFileSystem);  	kzfree(buf_to_free->password); +	kfree(buf_to_free->crfid.fid);  	kfree(buf_to_free);  } @@ -145,7 +151,7 @@ cifs_buf_get(void)  	 * SMB2 header is bigger than CIFS one - no problems to clean some  	 * more bytes for CIFS.  	 */ -	size_t buf_size = sizeof(struct smb2_hdr); +	size_t buf_size = sizeof(struct smb2_sync_hdr);  	/*  	 * We could use negotiated size instead of max_msgsize - @@ -339,7 +345,7 @@ checkSMB(char *buf, unsigned int total_read, struct TCP_Server_Info *server)  	/* otherwise, there is enough to get to the BCC */  	if (check_smb_hdr(smb))  		return -EIO; -	clc_len = smbCalcSize(smb); +	clc_len = smbCalcSize(smb, server);  	if (4 + rfclen != total_read) {  		cifs_dbg(VFS, "Length read does not match RFC1001 length %d\n", @@ -786,7 +792,7 @@ setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw)  				   GFP_KERNEL);  	if (!bv) { -		bv = vmalloc(max_pages * sizeof(struct bio_vec)); +		bv = vmalloc(array_size(max_pages, sizeof(struct bio_vec)));  		if (!bv)  			return -ENOMEM;  	} @@ -796,7 +802,7 @@ setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw)  				      GFP_KERNEL);  	if (!pages) { -		pages = vmalloc(max_pages * sizeof(struct page *)); +		pages = vmalloc(array_size(max_pages, sizeof(struct page *)));  		if (!pages) {  			kvfree(bv);  			return -ENOMEM; @@ -902,3 +908,20 @@ cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc)  		crypto_free_shash(*shash);  	*shash = NULL;  } + +/** + * rqst_page_get_length - obtain the length and offset for a page in smb_rqst + * Input: rqst - a smb_rqst, page - a page index for rqst + * Output: *len - the length for this page, *offset - the offset for this page + */ +void rqst_page_get_length(struct smb_rqst *rqst, unsigned int page, +				unsigned int *len, unsigned int *offset) +{ +	*len = rqst->rq_pagesz; +	*offset = (page == 0) ? rqst->rq_offset : 0; + +	if (rqst->rq_npages == 1 || page == rqst->rq_npages-1) +		*len = rqst->rq_tailsz; +	else if (page == 0) +		*len = rqst->rq_pagesz - rqst->rq_offset; +}  |