Skip to content

Commit 88c5060

Browse files
committed
Merge tag '5.18-rc3-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6
Pull cifs fixes from Steve French: "Four fixes, two of them for stable: - fcollapse fix - reconnect lock fix - DFS oops fix - minor cleanup patch" * tag '5.18-rc3-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6: cifs: destage any unwritten data to the server before calling copychunk_write cifs: use correct lock type in cifs_reconnect() cifs: fix NULL ptr dereference in refresh_mounts() cifs: Use kzalloc instead of kmalloc/memset
2 parents 279b83c + f5d0f92 commit 88c5060

File tree

4 files changed

+31
-10
lines changed

4 files changed

+31
-10
lines changed

fs/cifs/connect.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,12 +534,19 @@ int cifs_reconnect(struct TCP_Server_Info *server, bool mark_smb_session)
534534
{
535535
/* If tcp session is not an dfs connection, then reconnect to last target server */
536536
spin_lock(&cifs_tcp_ses_lock);
537-
if (!server->is_dfs_conn || !server->origin_fullpath || !server->leaf_fullpath) {
537+
if (!server->is_dfs_conn) {
538538
spin_unlock(&cifs_tcp_ses_lock);
539539
return __cifs_reconnect(server, mark_smb_session);
540540
}
541541
spin_unlock(&cifs_tcp_ses_lock);
542542

543+
mutex_lock(&server->refpath_lock);
544+
if (!server->origin_fullpath || !server->leaf_fullpath) {
545+
mutex_unlock(&server->refpath_lock);
546+
return __cifs_reconnect(server, mark_smb_session);
547+
}
548+
mutex_unlock(&server->refpath_lock);
549+
543550
return reconnect_dfs_server(server);
544551
}
545552
#else
@@ -3675,9 +3682,11 @@ static void setup_server_referral_paths(struct mount_ctx *mnt_ctx)
36753682
{
36763683
struct TCP_Server_Info *server = mnt_ctx->server;
36773684

3685+
mutex_lock(&server->refpath_lock);
36783686
server->origin_fullpath = mnt_ctx->origin_fullpath;
36793687
server->leaf_fullpath = mnt_ctx->leaf_fullpath;
36803688
server->current_fullpath = mnt_ctx->leaf_fullpath;
3689+
mutex_unlock(&server->refpath_lock);
36813690
mnt_ctx->origin_fullpath = mnt_ctx->leaf_fullpath = NULL;
36823691
}
36833692

fs/cifs/dfs_cache.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1422,12 +1422,14 @@ static int refresh_tcon(struct cifs_ses **sessions, struct cifs_tcon *tcon, bool
14221422
struct TCP_Server_Info *server = tcon->ses->server;
14231423

14241424
mutex_lock(&server->refpath_lock);
1425-
if (strcasecmp(server->leaf_fullpath, server->origin_fullpath))
1426-
__refresh_tcon(server->leaf_fullpath + 1, sessions, tcon, force_refresh);
1425+
if (server->origin_fullpath) {
1426+
if (server->leaf_fullpath && strcasecmp(server->leaf_fullpath,
1427+
server->origin_fullpath))
1428+
__refresh_tcon(server->leaf_fullpath + 1, sessions, tcon, force_refresh);
1429+
__refresh_tcon(server->origin_fullpath + 1, sessions, tcon, force_refresh);
1430+
}
14271431
mutex_unlock(&server->refpath_lock);
14281432

1429-
__refresh_tcon(server->origin_fullpath + 1, sessions, tcon, force_refresh);
1430-
14311433
return 0;
14321434
}
14331435

@@ -1530,11 +1532,14 @@ static void refresh_mounts(struct cifs_ses **sessions)
15301532
list_del_init(&tcon->ulist);
15311533

15321534
mutex_lock(&server->refpath_lock);
1533-
if (strcasecmp(server->leaf_fullpath, server->origin_fullpath))
1534-
__refresh_tcon(server->leaf_fullpath + 1, sessions, tcon, false);
1535+
if (server->origin_fullpath) {
1536+
if (server->leaf_fullpath && strcasecmp(server->leaf_fullpath,
1537+
server->origin_fullpath))
1538+
__refresh_tcon(server->leaf_fullpath + 1, sessions, tcon, false);
1539+
__refresh_tcon(server->origin_fullpath + 1, sessions, tcon, false);
1540+
}
15351541
mutex_unlock(&server->refpath_lock);
15361542

1537-
__refresh_tcon(server->origin_fullpath + 1, sessions, tcon, false);
15381543
cifs_put_tcon(tcon);
15391544
}
15401545
}

fs/cifs/smb2ops.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1858,9 +1858,17 @@ smb2_copychunk_range(const unsigned int xid,
18581858
int chunks_copied = 0;
18591859
bool chunk_sizes_updated = false;
18601860
ssize_t bytes_written, total_bytes_written = 0;
1861+
struct inode *inode;
18611862

18621863
pcchunk = kmalloc(sizeof(struct copychunk_ioctl), GFP_KERNEL);
18631864

1865+
/*
1866+
* We need to flush all unwritten data before we can send the
1867+
* copychunk ioctl to the server.
1868+
*/
1869+
inode = d_inode(trgtfile->dentry);
1870+
filemap_write_and_wait(inode->i_mapping);
1871+
18641872
if (pcchunk == NULL)
18651873
return -ENOMEM;
18661874

fs/cifs/transport.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -464,13 +464,12 @@ smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
464464
return -EIO;
465465
}
466466

467-
tr_hdr = kmalloc(sizeof(*tr_hdr), GFP_NOFS);
467+
tr_hdr = kzalloc(sizeof(*tr_hdr), GFP_NOFS);
468468
if (!tr_hdr)
469469
return -ENOMEM;
470470

471471
memset(&cur_rqst[0], 0, sizeof(cur_rqst));
472472
memset(&iov, 0, sizeof(iov));
473-
memset(tr_hdr, 0, sizeof(*tr_hdr));
474473

475474
iov.iov_base = tr_hdr;
476475
iov.iov_len = sizeof(*tr_hdr);

0 commit comments

Comments
 (0)