Skip to content

Commit 33c9de2

Browse files
committed
Merge tag '6.11-rc-part1-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6
Pull smb client fixes from Steve French: "Six smb3 client fixes, most for stable including important netfs fixes: - various netfs related fixes for cifs addressing some regressions in 6.10 (e.g. generic/708 and some multichannel crediting related issues) - fix for a noisy log message on copy_file_range - add trace point for read/write credits" * tag '6.11-rc-part1-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6: cifs: Fix missing fscache invalidation cifs: Add a tracepoint to track credits involved in R/W requests cifs: Fix setting of zero_point after DIO write cifs: Fix missing error code set cifs: Fix server re-repick on subrequest retry cifs: fix noisy message on copy_file_range
2 parents 8e31321 + a07d38a commit 33c9de2

File tree

8 files changed

+191
-31
lines changed

8 files changed

+191
-31
lines changed

fs/smb/client/cifsfs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1359,7 +1359,7 @@ ssize_t cifs_file_copychunk_range(unsigned int xid,
13591359
target_tcon = tlink_tcon(smb_file_target->tlink);
13601360

13611361
if (src_tcon->ses != target_tcon->ses) {
1362-
cifs_dbg(VFS, "source and target of copy not on same server\n");
1362+
cifs_dbg(FYI, "source and target of copy not on same server\n");
13631363
goto out;
13641364
}
13651365

fs/smb/client/cifsglob.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ struct smb_version_operations {
290290
int (*check_receive)(struct mid_q_entry *, struct TCP_Server_Info *,
291291
bool);
292292
void (*add_credits)(struct TCP_Server_Info *server,
293-
const struct cifs_credits *credits,
293+
struct cifs_credits *credits,
294294
const int optype);
295295
void (*set_credits)(struct TCP_Server_Info *, const int);
296296
int * (*get_credits_field)(struct TCP_Server_Info *, const int);
@@ -550,8 +550,8 @@ struct smb_version_operations {
550550
size_t *, struct cifs_credits *);
551551
/* adjust previously taken mtu credits to request size */
552552
int (*adjust_credits)(struct TCP_Server_Info *server,
553-
struct cifs_credits *credits,
554-
const unsigned int payload_size);
553+
struct cifs_io_subrequest *subreq,
554+
unsigned int /*enum smb3_rw_credits_trace*/ trace);
555555
/* check if we need to issue closedir */
556556
bool (*dir_needs_close)(struct cifsFileInfo *);
557557
long (*fallocate)(struct file *, struct cifs_tcon *, int, loff_t,
@@ -848,6 +848,9 @@ static inline void cifs_server_unlock(struct TCP_Server_Info *server)
848848
struct cifs_credits {
849849
unsigned int value;
850850
unsigned int instance;
851+
unsigned int in_flight_check;
852+
unsigned int rreq_debug_id;
853+
unsigned int rreq_debug_index;
851854
};
852855

853856
static inline unsigned int
@@ -873,7 +876,7 @@ has_credits(struct TCP_Server_Info *server, int *credits, int num_credits)
873876
}
874877

875878
static inline void
876-
add_credits(struct TCP_Server_Info *server, const struct cifs_credits *credits,
879+
add_credits(struct TCP_Server_Info *server, struct cifs_credits *credits,
877880
const int optype)
878881
{
879882
server->ops->add_credits(server, credits, optype);
@@ -897,11 +900,11 @@ set_credits(struct TCP_Server_Info *server, const int val)
897900
}
898901

899902
static inline int
900-
adjust_credits(struct TCP_Server_Info *server, struct cifs_credits *credits,
901-
const unsigned int payload_size)
903+
adjust_credits(struct TCP_Server_Info *server, struct cifs_io_subrequest *subreq,
904+
unsigned int /* enum smb3_rw_credits_trace */ trace)
902905
{
903906
return server->ops->adjust_credits ?
904-
server->ops->adjust_credits(server, credits, payload_size) : 0;
907+
server->ops->adjust_credits(server, subreq, trace) : 0;
905908
}
906909

907910
static inline __le64

fs/smb/client/file.c

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,16 @@ static void cifs_prepare_write(struct netfs_io_subrequest *subreq)
8080
return netfs_prepare_write_failed(subreq);
8181
}
8282

83+
wdata->credits.rreq_debug_id = subreq->rreq->debug_id;
84+
wdata->credits.rreq_debug_index = subreq->debug_index;
85+
wdata->credits.in_flight_check = 1;
86+
trace_smb3_rw_credits(wdata->rreq->debug_id,
87+
wdata->subreq.debug_index,
88+
wdata->credits.value,
89+
server->credits, server->in_flight,
90+
wdata->credits.value,
91+
cifs_trace_rw_credits_write_prepare);
92+
8393
#ifdef CONFIG_CIFS_SMB_DIRECT
8494
if (server->smbd_conn)
8595
subreq->max_nr_segs = server->smbd_conn->max_frmr_depth;
@@ -101,7 +111,7 @@ static void cifs_issue_write(struct netfs_io_subrequest *subreq)
101111
goto fail;
102112
}
103113

104-
rc = adjust_credits(wdata->server, &wdata->credits, wdata->subreq.len);
114+
rc = adjust_credits(wdata->server, wdata, cifs_trace_rw_credits_issue_write_adjust);
105115
if (rc)
106116
goto fail;
107117

@@ -123,6 +133,11 @@ static void cifs_issue_write(struct netfs_io_subrequest *subreq)
123133
goto out;
124134
}
125135

136+
static void cifs_netfs_invalidate_cache(struct netfs_io_request *wreq)
137+
{
138+
cifs_invalidate_cache(wreq->inode, 0);
139+
}
140+
126141
/*
127142
* Split the read up according to how many credits we can get for each piece.
128143
* It's okay to sleep here if we need to wait for more credit to become
@@ -158,7 +173,18 @@ static bool cifs_clamp_length(struct netfs_io_subrequest *subreq)
158173
return false;
159174
}
160175

176+
rdata->credits.in_flight_check = 1;
177+
rdata->credits.rreq_debug_id = rreq->debug_id;
178+
rdata->credits.rreq_debug_index = subreq->debug_index;
179+
180+
trace_smb3_rw_credits(rdata->rreq->debug_id,
181+
rdata->subreq.debug_index,
182+
rdata->credits.value,
183+
server->credits, server->in_flight, 0,
184+
cifs_trace_rw_credits_read_submit);
185+
161186
subreq->len = min_t(size_t, subreq->len, rsize);
187+
162188
#ifdef CONFIG_CIFS_SMB_DIRECT
163189
if (server->smbd_conn)
164190
subreq->max_nr_segs = server->smbd_conn->max_frmr_depth;
@@ -289,6 +315,15 @@ static void cifs_free_subrequest(struct netfs_io_subrequest *subreq)
289315
#endif
290316
}
291317

318+
if (rdata->credits.value != 0)
319+
trace_smb3_rw_credits(rdata->rreq->debug_id,
320+
rdata->subreq.debug_index,
321+
rdata->credits.value,
322+
rdata->server ? rdata->server->credits : 0,
323+
rdata->server ? rdata->server->in_flight : 0,
324+
-rdata->credits.value,
325+
cifs_trace_rw_credits_free_subreq);
326+
292327
add_credits_and_wake_if(rdata->server, &rdata->credits, 0);
293328
if (rdata->have_xid)
294329
free_xid(rdata->xid);
@@ -307,6 +342,7 @@ const struct netfs_request_ops cifs_req_ops = {
307342
.begin_writeback = cifs_begin_writeback,
308343
.prepare_write = cifs_prepare_write,
309344
.issue_write = cifs_issue_write,
345+
.invalidate_cache = cifs_netfs_invalidate_cache,
310346
};
311347

312348
/*
@@ -2358,13 +2394,18 @@ void cifs_write_subrequest_terminated(struct cifs_io_subrequest *wdata, ssize_t
23582394
bool was_async)
23592395
{
23602396
struct netfs_io_request *wreq = wdata->rreq;
2361-
loff_t new_server_eof;
2397+
struct netfs_inode *ictx = netfs_inode(wreq->inode);
2398+
loff_t wrend;
23622399

23632400
if (result > 0) {
2364-
new_server_eof = wdata->subreq.start + wdata->subreq.transferred + result;
2401+
wrend = wdata->subreq.start + wdata->subreq.transferred + result;
23652402

2366-
if (new_server_eof > netfs_inode(wreq->inode)->remote_i_size)
2367-
netfs_resize_file(netfs_inode(wreq->inode), new_server_eof, true);
2403+
if (wrend > ictx->zero_point &&
2404+
(wdata->rreq->origin == NETFS_UNBUFFERED_WRITE ||
2405+
wdata->rreq->origin == NETFS_DIO_WRITE))
2406+
ictx->zero_point = wrend;
2407+
if (wrend > ictx->remote_i_size)
2408+
netfs_resize_file(ictx, wrend, true);
23682409
}
23692410

23702411
netfs_write_subrequest_terminated(&wdata->subreq, result, was_async);
@@ -2877,6 +2918,7 @@ cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to)
28772918
rc = netfs_start_io_direct(inode);
28782919
if (rc < 0)
28792920
goto out;
2921+
rc = -EACCES;
28802922
down_read(&cinode->lock_sem);
28812923
if (!cifs_find_lock_conflict(
28822924
cfile, iocb->ki_pos, iov_iter_count(to),
@@ -2889,6 +2931,7 @@ cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to)
28892931
rc = netfs_start_io_read(inode);
28902932
if (rc < 0)
28912933
goto out;
2934+
rc = -EACCES;
28922935
down_read(&cinode->lock_sem);
28932936
if (!cifs_find_lock_conflict(
28942937
cfile, iocb->ki_pos, iov_iter_count(to),

fs/smb/client/smb1ops.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ cifs_find_mid(struct TCP_Server_Info *server, char *buffer)
108108

109109
static void
110110
cifs_add_credits(struct TCP_Server_Info *server,
111-
const struct cifs_credits *credits, const int optype)
111+
struct cifs_credits *credits, const int optype)
112112
{
113113
spin_lock(&server->req_lock);
114114
server->credits += credits->value;

fs/smb/client/smb2ops.c

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ change_conf(struct TCP_Server_Info *server)
6666

6767
static void
6868
smb2_add_credits(struct TCP_Server_Info *server,
69-
const struct cifs_credits *credits, const int optype)
69+
struct cifs_credits *credits, const int optype)
7070
{
7171
int *val, rc = -1;
7272
int scredits, in_flight;
@@ -94,7 +94,21 @@ smb2_add_credits(struct TCP_Server_Info *server,
9494
server->conn_id, server->hostname, *val,
9595
add, server->in_flight);
9696
}
97-
WARN_ON_ONCE(server->in_flight == 0);
97+
if (credits->in_flight_check > 1) {
98+
pr_warn_once("rreq R=%08x[%x] Credits not in flight\n",
99+
credits->rreq_debug_id, credits->rreq_debug_index);
100+
} else {
101+
credits->in_flight_check = 2;
102+
}
103+
if (WARN_ON_ONCE(server->in_flight == 0)) {
104+
pr_warn_once("rreq R=%08x[%x] Zero in_flight\n",
105+
credits->rreq_debug_id, credits->rreq_debug_index);
106+
trace_smb3_rw_credits(credits->rreq_debug_id,
107+
credits->rreq_debug_index,
108+
credits->value,
109+
server->credits, server->in_flight, 0,
110+
cifs_trace_rw_credits_zero_in_flight);
111+
}
98112
server->in_flight--;
99113
if (server->in_flight == 0 &&
100114
((optype & CIFS_OP_MASK) != CIFS_NEG_OP) &&
@@ -283,16 +297,23 @@ smb2_wait_mtu_credits(struct TCP_Server_Info *server, size_t size,
283297

284298
static int
285299
smb2_adjust_credits(struct TCP_Server_Info *server,
286-
struct cifs_credits *credits,
287-
const unsigned int payload_size)
300+
struct cifs_io_subrequest *subreq,
301+
unsigned int /*enum smb3_rw_credits_trace*/ trace)
288302
{
289-
int new_val = DIV_ROUND_UP(payload_size, SMB2_MAX_BUFFER_SIZE);
303+
struct cifs_credits *credits = &subreq->credits;
304+
int new_val = DIV_ROUND_UP(subreq->subreq.len, SMB2_MAX_BUFFER_SIZE);
290305
int scredits, in_flight;
291306

292307
if (!credits->value || credits->value == new_val)
293308
return 0;
294309

295310
if (credits->value < new_val) {
311+
trace_smb3_rw_credits(subreq->rreq->debug_id,
312+
subreq->subreq.debug_index,
313+
credits->value,
314+
server->credits, server->in_flight,
315+
new_val - credits->value,
316+
cifs_trace_rw_credits_no_adjust_up);
296317
trace_smb3_too_many_credits(server->CurrentMid,
297318
server->conn_id, server->hostname, 0, credits->value - new_val, 0);
298319
cifs_server_dbg(VFS, "request has less credits (%d) than required (%d)",
@@ -308,6 +329,12 @@ smb2_adjust_credits(struct TCP_Server_Info *server,
308329
in_flight = server->in_flight;
309330
spin_unlock(&server->req_lock);
310331

332+
trace_smb3_rw_credits(subreq->rreq->debug_id,
333+
subreq->subreq.debug_index,
334+
credits->value,
335+
server->credits, server->in_flight,
336+
new_val - credits->value,
337+
cifs_trace_rw_credits_old_session);
311338
trace_smb3_reconnect_detected(server->CurrentMid,
312339
server->conn_id, server->hostname, scredits,
313340
credits->value - new_val, in_flight);
@@ -316,6 +343,11 @@ smb2_adjust_credits(struct TCP_Server_Info *server,
316343
return -EAGAIN;
317344
}
318345

346+
trace_smb3_rw_credits(subreq->rreq->debug_id,
347+
subreq->subreq.debug_index,
348+
credits->value,
349+
server->credits, server->in_flight,
350+
new_val - credits->value, trace);
319351
server->credits += credits->value - new_val;
320352
scredits = server->credits;
321353
in_flight = server->in_flight;

fs/smb/client/smb2pdu.c

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4502,8 +4502,15 @@ smb2_readv_callback(struct mid_q_entry *mid)
45024502
struct TCP_Server_Info *server = rdata->server;
45034503
struct smb2_hdr *shdr =
45044504
(struct smb2_hdr *)rdata->iov[0].iov_base;
4505-
struct cifs_credits credits = { .value = 0, .instance = 0 };
4505+
struct cifs_credits credits = {
4506+
.value = 0,
4507+
.instance = 0,
4508+
.rreq_debug_id = rdata->rreq->debug_id,
4509+
.rreq_debug_index = rdata->subreq.debug_index,
4510+
};
45064511
struct smb_rqst rqst = { .rq_iov = &rdata->iov[1], .rq_nvec = 1 };
4512+
unsigned int rreq_debug_id = rdata->rreq->debug_id;
4513+
unsigned int subreq_debug_index = rdata->subreq.debug_index;
45074514

45084515
if (rdata->got_bytes) {
45094516
rqst.rq_iter = rdata->subreq.io_iter;
@@ -4587,10 +4594,16 @@ smb2_readv_callback(struct mid_q_entry *mid)
45874594
if (rdata->subreq.start < rdata->subreq.rreq->i_size)
45884595
rdata->result = 0;
45894596
}
4597+
trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, rdata->credits.value,
4598+
server->credits, server->in_flight,
4599+
0, cifs_trace_rw_credits_read_response_clear);
45904600
rdata->credits.value = 0;
45914601
INIT_WORK(&rdata->subreq.work, smb2_readv_worker);
45924602
queue_work(cifsiod_wq, &rdata->subreq.work);
45934603
release_mid(mid);
4604+
trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, 0,
4605+
server->credits, server->in_flight,
4606+
credits.value, cifs_trace_rw_credits_read_response_add);
45944607
add_credits(server, &credits, 0);
45954608
}
45964609

@@ -4647,7 +4660,7 @@ smb2_async_readv(struct cifs_io_subrequest *rdata)
46474660
min_t(int, server->max_credits -
46484661
server->credits, credit_request));
46494662

4650-
rc = adjust_credits(server, &rdata->credits, rdata->subreq.len);
4663+
rc = adjust_credits(server, rdata, cifs_trace_rw_credits_call_readv_adjust);
46514664
if (rc)
46524665
goto async_readv_out;
46534666

@@ -4766,7 +4779,14 @@ smb2_writev_callback(struct mid_q_entry *mid)
47664779
struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
47674780
struct TCP_Server_Info *server = wdata->server;
47684781
struct smb2_write_rsp *rsp = (struct smb2_write_rsp *)mid->resp_buf;
4769-
struct cifs_credits credits = { .value = 0, .instance = 0 };
4782+
struct cifs_credits credits = {
4783+
.value = 0,
4784+
.instance = 0,
4785+
.rreq_debug_id = wdata->rreq->debug_id,
4786+
.rreq_debug_index = wdata->subreq.debug_index,
4787+
};
4788+
unsigned int rreq_debug_id = wdata->rreq->debug_id;
4789+
unsigned int subreq_debug_index = wdata->subreq.debug_index;
47704790
ssize_t result = 0;
47714791
size_t written;
47724792

@@ -4837,9 +4857,15 @@ smb2_writev_callback(struct mid_q_entry *mid)
48374857
tcon->tid, tcon->ses->Suid,
48384858
wdata->subreq.start, wdata->subreq.len);
48394859

4860+
trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, wdata->credits.value,
4861+
server->credits, server->in_flight,
4862+
0, cifs_trace_rw_credits_write_response_clear);
48404863
wdata->credits.value = 0;
48414864
cifs_write_subrequest_terminated(wdata, result ?: written, true);
48424865
release_mid(mid);
4866+
trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, 0,
4867+
server->credits, server->in_flight,
4868+
credits.value, cifs_trace_rw_credits_write_response_add);
48434869
add_credits(server, &credits, 0);
48444870
}
48454871

@@ -4859,9 +4885,6 @@ smb2_async_writev(struct cifs_io_subrequest *wdata)
48594885
struct cifs_io_parms *io_parms = NULL;
48604886
int credit_request;
48614887

4862-
if (!wdata->server || test_bit(NETFS_SREQ_RETRYING, &wdata->subreq.flags))
4863-
server = wdata->server = cifs_pick_channel(tcon->ses);
4864-
48654888
/*
48664889
* in future we may get cifs_io_parms passed in from the caller,
48674890
* but for now we construct it here...
@@ -4972,7 +4995,7 @@ smb2_async_writev(struct cifs_io_subrequest *wdata)
49724995
min_t(int, server->max_credits -
49734996
server->credits, credit_request));
49744997

4975-
rc = adjust_credits(server, &wdata->credits, io_parms->length);
4998+
rc = adjust_credits(server, wdata, cifs_trace_rw_credits_call_writev_adjust);
49764999
if (rc)
49775000
goto async_writev_out;
49785001

@@ -4997,6 +5020,12 @@ smb2_async_writev(struct cifs_io_subrequest *wdata)
49975020
cifs_small_buf_release(req);
49985021
out:
49995022
if (rc) {
5023+
trace_smb3_rw_credits(wdata->rreq->debug_id,
5024+
wdata->subreq.debug_index,
5025+
wdata->credits.value,
5026+
server->credits, server->in_flight,
5027+
-(int)wdata->credits.value,
5028+
cifs_trace_rw_credits_write_response_clear);
50005029
add_credits_and_wake_if(wdata->server, &wdata->credits, 0);
50015030
cifs_write_subrequest_terminated(wdata, rc, true);
50025031
}

0 commit comments

Comments
 (0)