Skip to content

Commit 105b6c0

Browse files
committed
Merge tag '5.18-smb3-fixes-part1' of git://git.samba.org/sfrench/cifs-2.6
Pull cfis updates from Steve French: "Handlecache, unmount, fiemap and two reconnect fixes" * tag '5.18-smb3-fixes-part1' of git://git.samba.org/sfrench/cifs-2.6: cifs: use a different reconnect helper for non-cifsd threads cifs: we do not need a spinlock around the tree access during umount Adjust cifssb maximum read size cifs: truncate the inode and mapping when we simulate fcollapse cifs: fix handlecache and multiuser
2 parents ef51068 + dca6581 commit 105b6c0

File tree

9 files changed

+85
-14
lines changed

9 files changed

+85
-14
lines changed

fs/cifs/cifs_swn.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -396,11 +396,11 @@ static int cifs_swn_resource_state_changed(struct cifs_swn_reg *swnreg, const ch
396396
switch (state) {
397397
case CIFS_SWN_RESOURCE_STATE_UNAVAILABLE:
398398
cifs_dbg(FYI, "%s: resource name '%s' become unavailable\n", __func__, name);
399-
cifs_mark_tcp_ses_conns_for_reconnect(swnreg->tcon->ses->server, true);
399+
cifs_signal_cifsd_for_reconnect(swnreg->tcon->ses->server, true);
400400
break;
401401
case CIFS_SWN_RESOURCE_STATE_AVAILABLE:
402402
cifs_dbg(FYI, "%s: resource name '%s' become available\n", __func__, name);
403-
cifs_mark_tcp_ses_conns_for_reconnect(swnreg->tcon->ses->server, true);
403+
cifs_signal_cifsd_for_reconnect(swnreg->tcon->ses->server, true);
404404
break;
405405
case CIFS_SWN_RESOURCE_STATE_UNKNOWN:
406406
cifs_dbg(FYI, "%s: resource name '%s' changed to unknown state\n", __func__, name);
@@ -498,7 +498,7 @@ static int cifs_swn_reconnect(struct cifs_tcon *tcon, struct sockaddr_storage *a
498498
goto unlock;
499499
}
500500

501-
cifs_mark_tcp_ses_conns_for_reconnect(tcon->ses->server, false);
501+
cifs_signal_cifsd_for_reconnect(tcon->ses->server, false);
502502

503503
unlock:
504504
mutex_unlock(&tcon->ses->server->srv_mutex);

fs/cifs/cifsfs.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,9 @@ cifs_read_super(struct super_block *sb)
210210
if (rc)
211211
goto out_no_root;
212212
/* tune readahead according to rsize if readahead size not set on mount */
213+
if (cifs_sb->ctx->rsize == 0)
214+
cifs_sb->ctx->rsize =
215+
tcon->ses->server->ops->negotiate_rsize(tcon, cifs_sb->ctx);
213216
if (cifs_sb->ctx->rasize)
214217
sb->s_bdi->ra_pages = cifs_sb->ctx->rasize / PAGE_SIZE;
215218
else
@@ -254,6 +257,9 @@ static void cifs_kill_sb(struct super_block *sb)
254257
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
255258
struct cifs_tcon *tcon;
256259
struct cached_fid *cfid;
260+
struct rb_root *root = &cifs_sb->tlink_tree;
261+
struct rb_node *node;
262+
struct tcon_link *tlink;
257263

258264
/*
259265
* We ned to release all dentries for the cached directories
@@ -263,16 +269,18 @@ static void cifs_kill_sb(struct super_block *sb)
263269
dput(cifs_sb->root);
264270
cifs_sb->root = NULL;
265271
}
266-
tcon = cifs_sb_master_tcon(cifs_sb);
267-
if (tcon) {
272+
node = rb_first(root);
273+
while (node != NULL) {
274+
tlink = rb_entry(node, struct tcon_link, tl_rbnode);
275+
tcon = tlink_tcon(tlink);
268276
cfid = &tcon->crfid;
269277
mutex_lock(&cfid->fid_mutex);
270278
if (cfid->dentry) {
271-
272279
dput(cfid->dentry);
273280
cfid->dentry = NULL;
274281
}
275282
mutex_unlock(&cfid->fid_mutex);
283+
node = rb_next(node);
276284
}
277285

278286
kill_anon_super(sb);

fs/cifs/cifsproto.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ extern int SendReceiveBlockingLock(const unsigned int xid,
132132
struct smb_hdr *out_buf,
133133
int *bytes_returned);
134134
void
135+
cifs_signal_cifsd_for_reconnect(struct TCP_Server_Info *server,
136+
bool all_channels);
137+
void
135138
cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server,
136139
bool mark_smb_session);
137140
extern int cifs_reconnect(struct TCP_Server_Info *server,

fs/cifs/connect.c

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,11 +162,51 @@ static void cifs_resolve_server(struct work_struct *work)
162162
mutex_unlock(&server->srv_mutex);
163163
}
164164

165+
/*
166+
* Update the tcpStatus for the server.
167+
* This is used to signal the cifsd thread to call cifs_reconnect
168+
* ONLY cifsd thread should call cifs_reconnect. For any other
169+
* thread, use this function
170+
*
171+
* @server: the tcp ses for which reconnect is needed
172+
* @all_channels: if this needs to be done for all channels
173+
*/
174+
void
175+
cifs_signal_cifsd_for_reconnect(struct TCP_Server_Info *server,
176+
bool all_channels)
177+
{
178+
struct TCP_Server_Info *pserver;
179+
struct cifs_ses *ses;
180+
int i;
181+
182+
/* If server is a channel, select the primary channel */
183+
pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
184+
185+
spin_lock(&cifs_tcp_ses_lock);
186+
if (!all_channels) {
187+
pserver->tcpStatus = CifsNeedReconnect;
188+
spin_unlock(&cifs_tcp_ses_lock);
189+
return;
190+
}
191+
192+
list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
193+
spin_lock(&ses->chan_lock);
194+
for (i = 0; i < ses->chan_count; i++)
195+
ses->chans[i].server->tcpStatus = CifsNeedReconnect;
196+
spin_unlock(&ses->chan_lock);
197+
}
198+
spin_unlock(&cifs_tcp_ses_lock);
199+
}
200+
165201
/*
166202
* Mark all sessions and tcons for reconnect.
203+
* IMPORTANT: make sure that this gets called only from
204+
* cifsd thread. For any other thread, use
205+
* cifs_signal_cifsd_for_reconnect
167206
*
207+
* @server: the tcp ses for which reconnect is needed
168208
* @server needs to be previously set to CifsNeedReconnect.
169-
*
209+
* @mark_smb_session: whether even sessions need to be marked
170210
*/
171211
void
172212
cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server,

fs/cifs/dfs_cache.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1355,7 +1355,7 @@ static void mark_for_reconnect_if_needed(struct cifs_tcon *tcon, struct dfs_cach
13551355
}
13561356

13571357
cifs_dbg(FYI, "%s: no cached or matched targets. mark dfs share for reconnect.\n", __func__);
1358-
cifs_mark_tcp_ses_conns_for_reconnect(tcon->ses->server, true);
1358+
cifs_signal_cifsd_for_reconnect(tcon->ses->server, true);
13591359
}
13601360

13611361
/* Refresh dfs referral of tcon and mark it for reconnect if needed */

fs/cifs/file.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3740,6 +3740,11 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
37403740
break;
37413741
}
37423742

3743+
if (cifs_sb->ctx->rsize == 0)
3744+
cifs_sb->ctx->rsize =
3745+
server->ops->negotiate_rsize(tlink_tcon(open_file->tlink),
3746+
cifs_sb->ctx);
3747+
37433748
rc = server->ops->wait_mtu_credits(server, cifs_sb->ctx->rsize,
37443749
&rsize, credits);
37453750
if (rc)
@@ -4474,6 +4479,11 @@ static void cifs_readahead(struct readahead_control *ractl)
44744479
}
44754480
}
44764481

4482+
if (cifs_sb->ctx->rsize == 0)
4483+
cifs_sb->ctx->rsize =
4484+
server->ops->negotiate_rsize(tlink_tcon(open_file->tlink),
4485+
cifs_sb->ctx);
4486+
44774487
rc = server->ops->wait_mtu_credits(server, cifs_sb->ctx->rsize,
44784488
&rsize, credits);
44794489
if (rc)

fs/cifs/smb1ops.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ cifs_get_next_mid(struct TCP_Server_Info *server)
228228
spin_unlock(&GlobalMid_Lock);
229229

230230
if (reconnect) {
231-
cifs_mark_tcp_ses_conns_for_reconnect(server, false);
231+
cifs_signal_cifsd_for_reconnect(server, false);
232232
}
233233

234234
return mid;

fs/cifs/smb2ops.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "smb2glob.h"
2626
#include "cifs_ioctl.h"
2727
#include "smbdirect.h"
28+
#include "fscache.h"
2829
#include "fs_context.h"
2930

3031
/* Change credits for different ops and return the total number of credits */
@@ -3887,29 +3888,38 @@ static long smb3_collapse_range(struct file *file, struct cifs_tcon *tcon,
38873888
{
38883889
int rc;
38893890
unsigned int xid;
3891+
struct inode *inode;
38903892
struct cifsFileInfo *cfile = file->private_data;
3893+
struct cifsInodeInfo *cifsi;
38913894
__le64 eof;
38923895

38933896
xid = get_xid();
38943897

3895-
if (off >= i_size_read(file->f_inode) ||
3896-
off + len >= i_size_read(file->f_inode)) {
3898+
inode = d_inode(cfile->dentry);
3899+
cifsi = CIFS_I(inode);
3900+
3901+
if (off >= i_size_read(inode) ||
3902+
off + len >= i_size_read(inode)) {
38973903
rc = -EINVAL;
38983904
goto out;
38993905
}
39003906

39013907
rc = smb2_copychunk_range(xid, cfile, cfile, off + len,
3902-
i_size_read(file->f_inode) - off - len, off);
3908+
i_size_read(inode) - off - len, off);
39033909
if (rc < 0)
39043910
goto out;
39053911

3906-
eof = cpu_to_le64(i_size_read(file->f_inode) - len);
3912+
eof = cpu_to_le64(i_size_read(inode) - len);
39073913
rc = SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
39083914
cfile->fid.volatile_fid, cfile->pid, &eof);
39093915
if (rc < 0)
39103916
goto out;
39113917

39123918
rc = 0;
3919+
3920+
cifsi->server_eof = i_size_read(inode) - len;
3921+
truncate_setsize(inode, cifsi->server_eof);
3922+
fscache_resize_cookie(cifs_inode_cookie(inode), cifsi->server_eof);
39133923
out:
39143924
free_xid(xid);
39153925
return rc;

fs/cifs/transport.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
430430
* be taken as the remainder of this one. We need to kill the
431431
* socket so the server throws away the partial SMB
432432
*/
433-
cifs_mark_tcp_ses_conns_for_reconnect(server, false);
433+
cifs_signal_cifsd_for_reconnect(server, false);
434434
trace_smb3_partial_send_reconnect(server->CurrentMid,
435435
server->conn_id, server->hostname);
436436
}

0 commit comments

Comments
 (0)