Skip to content

Commit 86987d8

Browse files
committed
Merge tag 'v6.11-rc5-client-fixes' of git://git.samba.org/sfrench/cifs-2.6
Pull smb client fixes from Steve French: - two RDMA/smbdirect fixes and a minor cleanup - punch hole fix * tag 'v6.11-rc5-client-fixes' of git://git.samba.org/sfrench/cifs-2.6: cifs: Fix FALLOC_FL_PUNCH_HOLE support smb/client: fix rdma usage in smb2_async_writev() smb/client: remove unused rq_iter_size from struct smb_rqst smb/client: avoid dereferencing rdata=NULL in smb2_new_read_req()
2 parents 46d22bf + 416871f commit 86987d8

File tree

4 files changed

+43
-27
lines changed

4 files changed

+43
-27
lines changed

fs/smb/client/cifsglob.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,6 @@ struct cifs_open_info_data {
254254
struct smb_rqst {
255255
struct kvec *rq_iov; /* array of kvecs */
256256
unsigned int rq_nvec; /* number of kvecs in array */
257-
size_t rq_iter_size; /* Amount of data in ->rq_iter */
258257
struct iov_iter rq_iter; /* Data iterator */
259258
struct xarray rq_buffer; /* Page buffer for encryption */
260259
};

fs/smb/client/cifssmb.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1713,7 +1713,6 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
17131713
rqst.rq_iov = iov;
17141714
rqst.rq_nvec = 2;
17151715
rqst.rq_iter = wdata->subreq.io_iter;
1716-
rqst.rq_iter_size = iov_iter_count(&wdata->subreq.io_iter);
17171716

17181717
cifs_dbg(FYI, "async write at %llu %zu bytes\n",
17191718
wdata->subreq.start, wdata->subreq.len);

fs/smb/client/smb2ops.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3305,6 +3305,7 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,
33053305
struct inode *inode = file_inode(file);
33063306
struct cifsFileInfo *cfile = file->private_data;
33073307
struct file_zero_data_information fsctl_buf;
3308+
unsigned long long end = offset + len, i_size, remote_i_size;
33083309
long rc;
33093310
unsigned int xid;
33103311
__u8 set_sparse = 1;
@@ -3336,6 +3337,27 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,
33363337
(char *)&fsctl_buf,
33373338
sizeof(struct file_zero_data_information),
33383339
CIFSMaxBufSize, NULL, NULL);
3340+
3341+
if (rc)
3342+
goto unlock;
3343+
3344+
/* If there's dirty data in the buffer that would extend the EOF if it
3345+
* were written, then we need to move the EOF marker over to the lower
3346+
* of the high end of the hole and the proposed EOF. The problem is
3347+
* that we locally hole-punch the tail of the dirty data, the proposed
3348+
* EOF update will end up in the wrong place.
3349+
*/
3350+
i_size = i_size_read(inode);
3351+
remote_i_size = netfs_inode(inode)->remote_i_size;
3352+
if (end > remote_i_size && i_size > remote_i_size) {
3353+
unsigned long long extend_to = umin(end, i_size);
3354+
rc = SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
3355+
cfile->fid.volatile_fid, cfile->pid, extend_to);
3356+
if (rc >= 0)
3357+
netfs_inode(inode)->remote_i_size = extend_to;
3358+
}
3359+
3360+
unlock:
33393361
filemap_invalidate_unlock(inode->i_mapping);
33403362
out:
33413363
inode_unlock(inode);
@@ -4446,7 +4468,6 @@ smb3_init_transform_rq(struct TCP_Server_Info *server, int num_rqst,
44464468
}
44474469
iov_iter_xarray(&new->rq_iter, ITER_SOURCE,
44484470
buffer, 0, size);
4449-
new->rq_iter_size = size;
44504471
}
44514472
}
44524473

@@ -4492,7 +4513,6 @@ decrypt_raw_data(struct TCP_Server_Info *server, char *buf,
44924513
rqst.rq_nvec = 2;
44934514
if (iter) {
44944515
rqst.rq_iter = *iter;
4495-
rqst.rq_iter_size = iov_iter_count(iter);
44964516
iter_size = iov_iter_count(iter);
44974517
}
44984518

fs/smb/client/smb2pdu.c

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4441,7 +4441,7 @@ smb2_new_read_req(void **buf, unsigned int *total_len,
44414441
* If we want to do a RDMA write, fill in and append
44424442
* smbd_buffer_descriptor_v1 to the end of read request
44434443
*/
4444-
if (smb3_use_rdma_offload(io_parms)) {
4444+
if (rdata && smb3_use_rdma_offload(io_parms)) {
44454445
struct smbd_buffer_descriptor_v1 *v1;
44464446
bool need_invalidate = server->dialect == SMB30_PROT_ID;
44474447

@@ -4523,7 +4523,6 @@ smb2_readv_callback(struct mid_q_entry *mid)
45234523

45244524
if (rdata->got_bytes) {
45254525
rqst.rq_iter = rdata->subreq.io_iter;
4526-
rqst.rq_iter_size = iov_iter_count(&rdata->subreq.io_iter);
45274526
}
45284527

45294528
WARN_ONCE(rdata->server != mid->server,
@@ -4914,6 +4913,13 @@ smb2_async_writev(struct cifs_io_subrequest *wdata)
49144913
if (rc)
49154914
goto out;
49164915

4916+
rqst.rq_iov = iov;
4917+
rqst.rq_iter = wdata->subreq.io_iter;
4918+
4919+
rqst.rq_iov[0].iov_len = total_len - 1;
4920+
rqst.rq_iov[0].iov_base = (char *)req;
4921+
rqst.rq_nvec += 1;
4922+
49174923
if (smb3_encryption_required(tcon))
49184924
flags |= CIFS_TRANSFORM_REQ;
49194925

@@ -4925,6 +4931,7 @@ smb2_async_writev(struct cifs_io_subrequest *wdata)
49254931
req->WriteChannelInfoOffset = 0;
49264932
req->WriteChannelInfoLength = 0;
49274933
req->Channel = SMB2_CHANNEL_NONE;
4934+
req->Length = cpu_to_le32(io_parms->length);
49284935
req->Offset = cpu_to_le64(io_parms->offset);
49294936
req->DataOffset = cpu_to_le16(
49304937
offsetof(struct smb2_write_req, Buffer));
@@ -4944,7 +4951,6 @@ smb2_async_writev(struct cifs_io_subrequest *wdata)
49444951
*/
49454952
if (smb3_use_rdma_offload(io_parms)) {
49464953
struct smbd_buffer_descriptor_v1 *v1;
4947-
size_t data_size = iov_iter_count(&wdata->subreq.io_iter);
49484954
bool need_invalidate = server->dialect == SMB30_PROT_ID;
49494955

49504956
wdata->mr = smbd_register_mr(server->smbd_conn, &wdata->subreq.io_iter,
@@ -4953,9 +4959,10 @@ smb2_async_writev(struct cifs_io_subrequest *wdata)
49534959
rc = -EAGAIN;
49544960
goto async_writev_out;
49554961
}
4962+
/* For RDMA read, I/O size is in RemainingBytes not in Length */
4963+
req->RemainingBytes = req->Length;
49564964
req->Length = 0;
49574965
req->DataOffset = 0;
4958-
req->RemainingBytes = cpu_to_le32(data_size);
49594966
req->Channel = SMB2_CHANNEL_RDMA_V1_INVALIDATE;
49604967
if (need_invalidate)
49614968
req->Channel = SMB2_CHANNEL_RDMA_V1;
@@ -4967,31 +4974,22 @@ smb2_async_writev(struct cifs_io_subrequest *wdata)
49674974
v1->offset = cpu_to_le64(wdata->mr->mr->iova);
49684975
v1->token = cpu_to_le32(wdata->mr->mr->rkey);
49694976
v1->length = cpu_to_le32(wdata->mr->mr->length);
4977+
4978+
rqst.rq_iov[0].iov_len += sizeof(*v1);
4979+
4980+
/*
4981+
* We keep wdata->subreq.io_iter,
4982+
* but we have to truncate rqst.rq_iter
4983+
*/
4984+
iov_iter_truncate(&rqst.rq_iter, 0);
49704985
}
49714986
#endif
4972-
iov[0].iov_len = total_len - 1;
4973-
iov[0].iov_base = (char *)req;
49744987

4975-
rqst.rq_iov = iov;
4976-
rqst.rq_nvec = 1;
4977-
rqst.rq_iter = wdata->subreq.io_iter;
4978-
rqst.rq_iter_size = iov_iter_count(&rqst.rq_iter);
49794988
if (test_bit(NETFS_SREQ_RETRYING, &wdata->subreq.flags))
49804989
smb2_set_replay(server, &rqst);
4981-
#ifdef CONFIG_CIFS_SMB_DIRECT
4982-
if (wdata->mr)
4983-
iov[0].iov_len += sizeof(struct smbd_buffer_descriptor_v1);
4984-
#endif
4985-
cifs_dbg(FYI, "async write at %llu %u bytes iter=%zx\n",
4986-
io_parms->offset, io_parms->length, iov_iter_count(&rqst.rq_iter));
49874990

4988-
#ifdef CONFIG_CIFS_SMB_DIRECT
4989-
/* For RDMA read, I/O size is in RemainingBytes not in Length */
4990-
if (!wdata->mr)
4991-
req->Length = cpu_to_le32(io_parms->length);
4992-
#else
4993-
req->Length = cpu_to_le32(io_parms->length);
4994-
#endif
4991+
cifs_dbg(FYI, "async write at %llu %u bytes iter=%zx\n",
4992+
io_parms->offset, io_parms->length, iov_iter_count(&wdata->subreq.io_iter));
49954993

49964994
if (wdata->credits.value > 0) {
49974995
shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(wdata->subreq.len,

0 commit comments

Comments
 (0)