diff options
| author | Jan Engelmohr <jan.engelmohr@mailbox.tu-dresden.de> | 2016-09-04 16:45:09 +0200 |
|---|---|---|
| committer | Moyster <oysterized@gmail.com> | 2016-09-10 00:45:11 +0200 |
| commit | 0a1e8e11acd3cc36b1d65023ce1cb1a06a887b11 (patch) | |
| tree | bd92a01ee850567d86074cca3fb6c928c960fe39 /fs/cifs | |
| parent | ade0200dcde3ad70876875392b6bc156155b9b75 (diff) | |
3.10.102-> 3.10.103
Diffstat (limited to 'fs/cifs')
| -rw-r--r-- | fs/cifs/connect.c | 4 | ||||
| -rw-r--r-- | fs/cifs/dir.c | 24 | ||||
| -rw-r--r-- | fs/cifs/smb2pdu.c | 27 |
3 files changed, 51 insertions, 4 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index d05a30072..7c33afd7d 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -408,7 +408,9 @@ cifs_echo_request(struct work_struct *work) * server->ops->need_neg() == true. Also, no need to ping if * we got a response recently. */ - if (!server->ops->need_neg || server->ops->need_neg(server) || + + if (server->tcpStatus == CifsNeedReconnect || + server->tcpStatus == CifsExiting || server->tcpStatus == CifsNew || (server->ops->can_echo && !server->ops->can_echo(server)) || time_before(jiffies, server->lstrp + SMB_ECHO_INTERVAL - HZ)) goto requeue_echo; diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 0c2425b21..a998c9292 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -227,6 +227,13 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, goto cifs_create_get_file_info; } + if (S_ISDIR(newinode->i_mode)) { + CIFSSMBClose(xid, tcon, fid->netfid); + iput(newinode); + rc = -EISDIR; + goto out; + } + if (!S_ISREG(newinode->i_mode)) { /* * The server may allow us to open things like @@ -391,10 +398,14 @@ cifs_create_set_dentry: if (rc != 0) { cifs_dbg(FYI, "Create worked, get_inode_info failed rc = %d\n", rc); - if (server->ops->close) - server->ops->close(xid, tcon, fid); - goto out; + goto out_err; } + + if (S_ISDIR(newinode->i_mode)) { + rc = -EISDIR; + goto out_err; + } + d_drop(direntry); d_add(direntry, newinode); @@ -402,6 +413,13 @@ out: kfree(buf); kfree(full_path); return rc; + +out_err: + if (server->ops->close) + server->ops->close(xid, tcon, fid); + if (newinode) + iput(newinode); + goto out; } int diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index eb0de4c3c..9dd8c968d 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -1250,6 +1250,33 @@ SMB2_echo(struct TCP_Server_Info *server) cifs_dbg(FYI, "In echo request\n"); + if (server->tcpStatus == CifsNeedNegotiate) { + struct list_head *tmp, *tmp2; + struct cifs_ses *ses; + struct cifs_tcon *tcon; + + cifs_dbg(FYI, "Need negotiate, reconnecting tcons\n"); + spin_lock(&cifs_tcp_ses_lock); + list_for_each(tmp, &server->smb_ses_list) { + ses = list_entry(tmp, struct cifs_ses, smb_ses_list); + list_for_each(tmp2, &ses->tcon_list) { + tcon = list_entry(tmp2, struct cifs_tcon, + tcon_list); + /* add check for persistent handle reconnect */ + if (tcon && tcon->need_reconnect) { + spin_unlock(&cifs_tcp_ses_lock); + rc = smb2_reconnect(SMB2_ECHO, tcon); + spin_lock(&cifs_tcp_ses_lock); + } + } + } + spin_unlock(&cifs_tcp_ses_lock); + } + + /* if no session, renegotiate failed above */ + if (server->tcpStatus == CifsNeedNegotiate) + return -EIO; + rc = small_smb2_init(SMB2_ECHO, NULL, (void **)&req); if (rc) return rc; |
