Commit 76c178da authored by Steve French's avatar Steve French

Fix 20 second hang on some deletes of reopened file due to semaphore conflict...

Fix 20 second hang on some deletes of reopened file due to semaphore conflict with vfs_delete on i_sem
parent 105cbe3b
......@@ -2,7 +2,9 @@ Version 1.06
------------
Send NTCreateX with ATTR_POSIX if Linux/Unix extensions negotiated with server.
This allows files that differ only in case and improves performance of file
creation and file open to such servers.
creation and file open to such servers. Fix semaphore conflict which causes
slow delete of open file to Samba (which unfortunately can cause an oplock
break to self while vfs_unlink held i_sem) which can hang for 20 seconds.
Version 1.05
------------
......
......@@ -74,7 +74,7 @@ int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct cifsSesInfo * ses,
rc = cifs_calculate_signature(cifs_pdu, ses->mac_signing_key,smb_signature);
if(rc)
memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
else
memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8);
......@@ -88,15 +88,15 @@ int cifs_verify_signature(struct smb_hdr * cifs_pdu, const char * mac_key,
char server_response_sig[8];
char what_we_think_sig_should_be[20];
if((cifs_pdu == NULL) || (mac_key == NULL))
return -EINVAL;
if((cifs_pdu == NULL) || (mac_key == NULL))
return -EINVAL;
if (cifs_pdu->Command == SMB_COM_NEGOTIATE)
return 0;
if (cifs_pdu->Command == SMB_COM_LOCKING_ANDX) {
struct smb_com_lock_req * pSMB = (struct smb_com_lock_req *)cifs_pdu;
if(pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE)
if(pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE)
return 0;
}
......@@ -113,10 +113,10 @@ int cifs_verify_signature(struct smb_hdr * cifs_pdu, const char * mac_key,
its signature against what the server sent */
memcpy(server_response_sig,cifs_pdu->Signature.SecuritySignature,8);
cifs_pdu->Signature.Sequence.SequenceNumber = expected_sequence_number;
cifs_pdu->Signature.Sequence.Reserved = 0;
cifs_pdu->Signature.Sequence.SequenceNumber = expected_sequence_number;
cifs_pdu->Signature.Sequence.Reserved = 0;
rc = cifs_calculate_signature(cifs_pdu, mac_key,
rc = cifs_calculate_signature(cifs_pdu, mac_key,
what_we_think_sig_should_be);
if(rc)
......@@ -167,19 +167,19 @@ int CalcNTLMv2_partial_mac_key(struct cifsSesInfo * ses, struct nls_table * nls_
return -EINVAL;
ucase_buf = kmalloc((MAX_USERNAME_SIZE+1), GFP_KERNEL);
unicode_buf = kmalloc((MAX_USERNAME_SIZE+1)*4, GFP_KERNEL);
unicode_buf = kmalloc((MAX_USERNAME_SIZE+1)*4, GFP_KERNEL);
for(i=0;i<user_name_len;i++)
ucase_buf[i] = nls_info->charset2upper[(int)ses->userName[i]];
ucase_buf[i] = 0;
user_name_len = cifs_strtoUCS(unicode_buf, ucase_buf, MAX_USERNAME_SIZE*2, nls_info);
user_name_len = cifs_strtoUCS(unicode_buf, ucase_buf, MAX_USERNAME_SIZE*2, nls_info);
unicode_buf[user_name_len] = 0;
user_name_len++;
for(i=0;i<dom_name_len;i++)
ucase_buf[i] = nls_info->charset2upper[(int)ses->domainName[i]];
ucase_buf[i] = 0;
dom_name_len = cifs_strtoUCS(unicode_buf+user_name_len, ucase_buf, MAX_USERNAME_SIZE*2, nls_info);
for(i=0;i<dom_name_len;i++)
ucase_buf[i] = nls_info->charset2upper[(int)ses->domainName[i]];
ucase_buf[i] = 0;
dom_name_len = cifs_strtoUCS(unicode_buf+user_name_len, ucase_buf, MAX_USERNAME_SIZE*2, nls_info);
unicode_buf[user_name_len + dom_name_len] = 0;
hmac_md5_update((const unsigned char *) unicode_buf,
......@@ -200,6 +200,5 @@ void CalcNTLMv2_response(const struct cifsSesInfo * ses,char * v2_session_respon
hmac_md5_update(ses->server->cryptKey,8,&context);
/* hmac_md5_update(v2_session_response+16)client thing,8,&context); */ /* BB fix */
hmac_md5_final(v2_session_response,&context);
}
......@@ -631,19 +631,24 @@ static int cifs_oplock_thread(void * dummyarg)
oplock_item = list_entry(GlobalOplock_Q.next,
struct oplock_q_entry, qhead);
if(oplock_item) {
cFYI(1,("found oplock item to write out"));
pTcon = oplock_item->tcon;
inode = oplock_item->pinode;
netfid = oplock_item->netfid;
spin_unlock(&GlobalMid_Lock);
DeleteOplockQEntry(oplock_item);
down(&inode->i_sem);
/* can not grab inode sem here since it would
deadlock when oplock received on delete
since vfs_unlink holds the i_sem across
the call */
/* down(&inode->i_sem);*/
if (S_ISREG(inode->i_mode)) {
rc = filemap_fdatawrite(inode->i_mapping);
if(CIFS_I(inode)->clientCanCacheRead == 0)
invalidate_remote_inode(inode);
} else
rc = 0;
up(&inode->i_sem);
/* up(&inode->i_sem);*/
if (rc)
CIFS_I(inode)->write_behind_rc = rc;
cFYI(1,("Oplock flush inode %p rc %d",inode,rc));
......
......@@ -924,7 +924,6 @@ static void cifs_copy_cache_pages(struct address_space *mapping,
break;
page = list_entry(pages->prev, struct page, list);
/*cERROR(1,("copy_cache_pages page %p index %ld data %p",page,page->index,data));*/ /* BB removeme */
list_del(&page->list);
if (add_to_page_cache(page, mapping, page->index, GFP_KERNEL)) {
......@@ -1009,18 +1008,12 @@ cifs_readpages(struct file *file, struct address_space *mapping,
break;
}
}
/* cERROR(1,("ended with contig_pages %d since expected_index %d not matched",contig_pages,expected_index)); */
if(contig_pages + i > num_pages) {
/* cERROR(1,("reducing contig_pages from %d with i: %d",contig_pages,i));*/
contig_pages = num_pages - i;
}
/* for reads over a certain size could initiate async read ahead */
/* cERROR(1,("Read %d pages out of %d into cache at offset %ld ",
contig_pages, num_pages-i, (unsigned long) offset));*/ /* BB removeme BB */
read_size = contig_pages * PAGE_CACHE_SIZE;
/* Read size needs to be in multiples of one page */
read_size = min_t(const unsigned int,read_size,cifs_sb->rsize & PAGE_CACHE_MASK);
......@@ -1038,7 +1031,6 @@ cifs_readpages(struct file *file, struct address_space *mapping,
read_size, offset,
&bytes_read, &smb_read_data);
/* BB need to check return code here */
/* cERROR(1,("read size: %d bytes read: %d rc: %d",read_size,bytes_read,rc)); */ /* BB removeme BB */
}
if ((rc < 0) || (smb_read_data == NULL)) {
cERROR(1,("Read error in readpages: %d",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