Commit 1ba4886d authored by Steve French's avatar Steve French Committed by Steve French

fix rename of open files

parent d1b8ea55
...@@ -94,9 +94,14 @@ int cifs_verify_signature(struct smb_hdr * cifs_pdu, const char * mac_key, ...@@ -94,9 +94,14 @@ int cifs_verify_signature(struct smb_hdr * cifs_pdu, const char * mac_key,
if (cifs_pdu->Command == SMB_COM_NEGOTIATE) if (cifs_pdu->Command == SMB_COM_NEGOTIATE)
return 0; 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)
return 0;
}
/* BB what if signatures are supposed to be on for session but server does not /* BB what if signatures are supposed to be on for session but server does not
send one? BB */ send one? BB */
/* BB also do not verify oplock breaks for signature */
/* Do not need to verify session setups with signature "BSRSPYL " */ /* Do not need to verify session setups with signature "BSRSPYL " */
if(memcmp(cifs_pdu->Signature.SecuritySignature,"BSRSPYL ",8)==0) if(memcmp(cifs_pdu->Signature.SecuritySignature,"BSRSPYL ",8)==0)
......
...@@ -170,8 +170,8 @@ extern int CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon, ...@@ -170,8 +170,8 @@ extern int CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon,
extern int CIFSSMBRename(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
const char *fromName, const char *toName, const char *fromName, const char *toName,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSSMBDummyRenameOpenFile(const int xid,struct cifsTconInfo *pTcon, extern int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
int netfid, const struct nls_table *nls_codepage); int netfid, char * target_name, const struct nls_table *nls_codepage);
extern int CIFSCreateHardLink(const int xid, extern int CIFSCreateHardLink(const int xid,
struct cifsTconInfo *tcon, struct cifsTconInfo *tcon,
const char *fromName, const char *toName, const char *fromName, const char *toName,
......
...@@ -639,8 +639,9 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, ...@@ -639,8 +639,9 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
if (rc) if (rc)
return rc; return rc;
if(lockType == LOCKING_ANDX_OPLOCK_RELEASE) if(lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
timeout = -1; /* no response expected */ timeout = -1; /* no response expected */
}
pSMB->NumberOfLocks = cpu_to_le32(numLock); pSMB->NumberOfLocks = cpu_to_le32(numLock);
pSMB->NumberOfUnlocks = cpu_to_le32(numUnlock); pSMB->NumberOfUnlocks = cpu_to_le32(numUnlock);
...@@ -754,7 +755,7 @@ CIFSSMBRename(const int xid, struct cifsTconInfo *tcon, ...@@ -754,7 +755,7 @@ CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { if (rc) {
cFYI(1, ("Send error in RMDir = %d", rc)); cFYI(1, ("Send error in rename = %d", rc));
} }
if (pSMB) if (pSMB)
buf_release(pSMB); buf_release(pSMB);
...@@ -762,18 +763,19 @@ CIFSSMBRename(const int xid, struct cifsTconInfo *tcon, ...@@ -762,18 +763,19 @@ CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
return rc; return rc;
} }
int CIFSSMBDummyRenameOpenFile(const int xid,struct cifsTconInfo *pTcon, int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
int netfid, const struct nls_table * nls_codepage) int netfid, char * target_name, const struct nls_table * nls_codepage)
{ {
struct smb_com_transaction2_sfi_req *pSMB = NULL; struct smb_com_transaction2_sfi_req *pSMB = NULL;
struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
struct set_file_rename * rename_info; struct set_file_rename * rename_info;
char *data_offset; char *data_offset;
char dummy_string[30];
int rc = 0; int rc = 0;
int bytes_returned = 0; int bytes_returned = 0;
int len_of_str; int len_of_str;
cFYI(1, ("Rename to Dummy Random File Name")); cFYI(1, ("Rename to File by handle"));
rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB, rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
...@@ -805,12 +807,19 @@ int CIFSSMBDummyRenameOpenFile(const int xid,struct cifsTconInfo *pTcon, ...@@ -805,12 +807,19 @@ int CIFSSMBDummyRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
/* construct random name ".cifs_tmp<inodenum><mid>" */ /* construct random name ".cifs_tmp<inodenum><mid>" */
rename_info->overwrite = cpu_to_le32(1); rename_info->overwrite = cpu_to_le32(1);
rename_info->root_fid = 0; rename_info->root_fid = 0;
len_of_str = cifs_strtoUCS((wchar_t *) rename_info->target_name, ".cifs", 12, nls_codepage); /* unicode only call */
if(target_name == NULL) {
sprintf(dummy_string,"cifs%x",pSMB->hdr.Mid);
len_of_str = cifs_strtoUCS((wchar_t *) rename_info->target_name, dummy_string, 24, nls_codepage);
} else {
len_of_str = cifs_strtoUCS((wchar_t *) rename_info->target_name, target_name, 530, nls_codepage);
}
cFYI(1,("len of str: %d", len_of_str)); /* BB removeme BB */
rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
pSMB->DataCount = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str); pSMB->DataCount = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
pSMB->ByteCount += pSMB->DataCount; pSMB->ByteCount += pSMB->DataCount;
pSMB->DataCount = cpu_to_le16(pSMB->DataCount); pSMB->DataCount = cpu_to_le16(pSMB->DataCount);
pSMB->Fid = netfid; pSMB->Fid = netfid;
/* should we check the passthrough bit ? */
pSMB->InformationLevel = pSMB->InformationLevel =
cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION); cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
pSMB->Reserved4 = 0; pSMB->Reserved4 = 0;
...@@ -819,7 +828,7 @@ int CIFSSMBDummyRenameOpenFile(const int xid,struct cifsTconInfo *pTcon, ...@@ -819,7 +828,7 @@ int CIFSSMBDummyRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { if (rc) {
cFYI(1,("Send error in DummyRename = %d", rc)); cFYI(1,("Send error in Rename (by file handle) = %d", rc));
} }
if (pSMB) if (pSMB)
......
...@@ -102,7 +102,7 @@ cifs_reconnect(struct TCP_Server_Info *server) ...@@ -102,7 +102,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
} }
list_for_each(tmp, &GlobalTreeConnectionList) { list_for_each(tmp, &GlobalTreeConnectionList) {
tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
if(tcon->ses->server == server) { if((tcon) && (tcon->ses) && (tcon->ses->server == server)) {
tcon->tidStatus = CifsNeedReconnect; tcon->tidStatus = CifsNeedReconnect;
} }
} }
...@@ -728,6 +728,7 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket) ...@@ -728,6 +728,7 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket)
*csocket = NULL; *csocket = NULL;
return rc; return rc;
} else { } else {
/* BB other socket options to set KEEPALIVE, timeouts? NODELAY? */
cFYI(1,("Socket created")); cFYI(1,("Socket created"));
} }
} }
...@@ -783,6 +784,7 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket) ...@@ -783,6 +784,7 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
(struct sockaddr *) psin_server, (struct sockaddr *) psin_server,
sizeof (struct sockaddr_in6),0); sizeof (struct sockaddr_in6),0);
if (rc >= 0) { if (rc >= 0) {
/* BB other socket options to set KEEPALIVE, timeouts? NODELAY? */
return rc; return rc;
} }
} }
......
...@@ -353,8 +353,8 @@ cifs_unlink(struct inode *inode, struct dentry *direntry) ...@@ -353,8 +353,8 @@ cifs_unlink(struct inode *inode, struct dentry *direntry)
CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE, CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE,
&netfid, &oplock, NULL, cifs_sb->local_nls); &netfid, &oplock, NULL, cifs_sb->local_nls);
if(rc==0) { if(rc==0) {
CIFSSMBDummyRenameOpenFile(xid,pTcon,netfid, CIFSSMBRenameOpenFile(xid,pTcon,netfid,
cifs_sb->local_nls); NULL, cifs_sb->local_nls);
CIFSSMBClose(xid, pTcon, netfid); CIFSSMBClose(xid, pTcon, netfid);
direntry->d_inode->i_nlink--; direntry->d_inode->i_nlink--;
} }
...@@ -381,7 +381,7 @@ cifs_unlink(struct inode *inode, struct dentry *direntry) ...@@ -381,7 +381,7 @@ cifs_unlink(struct inode *inode, struct dentry *direntry)
CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE, CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE,
&netfid, &oplock, NULL, cifs_sb->local_nls); &netfid, &oplock, NULL, cifs_sb->local_nls);
if(rc==0) { if(rc==0) {
CIFSSMBDummyRenameOpenFile(xid,pTcon,netfid,cifs_sb->local_nls); CIFSSMBRenameOpenFile(xid,pTcon,netfid,NULL,cifs_sb->local_nls);
CIFSSMBClose(xid, pTcon, netfid); CIFSSMBClose(xid, pTcon, netfid);
direntry->d_inode->i_nlink--; direntry->d_inode->i_nlink--;
} }
...@@ -526,6 +526,20 @@ cifs_rename(struct inode *source_inode, struct dentry *source_direntry, ...@@ -526,6 +526,20 @@ cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
rc = CIFSSMBRename(xid, pTcon, fromName, toName, rc = CIFSSMBRename(xid, pTcon, fromName, toName,
cifs_sb_source->local_nls); cifs_sb_source->local_nls);
} }
if((rc == -EIO)||(rc == -EEXIST)) {
int oplock = FALSE;
__u16 netfid;
rc = CIFSSMBOpen(xid, pTcon, fromName, FILE_OPEN, GENERIC_READ,
CREATE_NOT_DIR,
&netfid, &oplock, NULL, cifs_sb_source->local_nls);
if(rc==0) {
CIFSSMBRenameOpenFile(xid,pTcon,netfid,
toName, cifs_sb_source->local_nls);
CIFSSMBClose(xid, pTcon, netfid);
}
}
if (fromName) if (fromName)
kfree(fromName); kfree(fromName);
if (toName) if (toName)
......
...@@ -169,7 +169,10 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, ...@@ -169,7 +169,10 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
temp_fs = get_fs(); /* we must turn off socket api parm checking */ temp_fs = get_fs(); /* we must turn off socket api parm checking */
set_fs(get_ds()); set_fs(get_ds());
rc = sock_sendmsg(ssocket, &smb_msg, smb_buf_length + 4); rc = sock_sendmsg(ssocket, &smb_msg, smb_buf_length + 4);
while(rc == -ENOSPC) {
schedule_timeout(HZ/2);
rc = sock_sendmsg(ssocket, &smb_msg, smb_buf_length + 4);
}
set_fs(temp_fs); set_fs(temp_fs);
if (rc < 0) { if (rc < 0) {
......
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