four cifs.ko client fixes
-----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAmbOBa8ACgkQiiy9cAdy T1GHBAwAmSK9FTCg4x5tTRBwiS9VSrC3KQ2TwLrkXjeWXhJycZjsDQHnbHG68Q+t Sbq711RClpdvwMWLUqiryjd+VVqPzG/9jZLOPeeW7SIljyksUzxaQXGbGcquz57N hnZjrjyyquU5NhtOALyVeO4lNYboYTH+fETsrMoJIGNoI0yBHZSM/eRQO1heLRBn 629yKbqp0m/5/A/w3s1nKljO74sG//6LKDZld6es7tmxgku8TFNEqsI7SONw3pUg dYgM2kIPf4rwpqupfxSriylz0xlHIEmITn5wkvygS+TvcWXsG855TVLjtD1I6uX3 JYOZ9gfqubGNXkT5SbbfsmAOma8PBm54oT0UWwJVUj/5Ed3D9EyBl2jlqjNLQjSU qJ0/ha+AyFCn2vviPA+vVnHd5I2Y82JlI4VrwrSyHG5E/6UMHNQ2Do8GbA/eRdcp HeqR57V4VNzNzVfKCp4XygwBuifbXdRX+yrUdBPDZm+CMLPD6wGZdUQu4FaESYv6 i24UdVG9 =BDrz -----END PGP SIGNATURE----- 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()
This commit is contained in:
commit
86987d84b9
@ -254,7 +254,6 @@ struct cifs_open_info_data {
|
||||
struct smb_rqst {
|
||||
struct kvec *rq_iov; /* array of kvecs */
|
||||
unsigned int rq_nvec; /* number of kvecs in array */
|
||||
size_t rq_iter_size; /* Amount of data in ->rq_iter */
|
||||
struct iov_iter rq_iter; /* Data iterator */
|
||||
struct xarray rq_buffer; /* Page buffer for encryption */
|
||||
};
|
||||
|
@ -1713,7 +1713,6 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
|
||||
rqst.rq_iov = iov;
|
||||
rqst.rq_nvec = 2;
|
||||
rqst.rq_iter = wdata->subreq.io_iter;
|
||||
rqst.rq_iter_size = iov_iter_count(&wdata->subreq.io_iter);
|
||||
|
||||
cifs_dbg(FYI, "async write at %llu %zu bytes\n",
|
||||
wdata->subreq.start, wdata->subreq.len);
|
||||
|
@ -3305,6 +3305,7 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,
|
||||
struct inode *inode = file_inode(file);
|
||||
struct cifsFileInfo *cfile = file->private_data;
|
||||
struct file_zero_data_information fsctl_buf;
|
||||
unsigned long long end = offset + len, i_size, remote_i_size;
|
||||
long rc;
|
||||
unsigned int xid;
|
||||
__u8 set_sparse = 1;
|
||||
@ -3336,6 +3337,27 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,
|
||||
(char *)&fsctl_buf,
|
||||
sizeof(struct file_zero_data_information),
|
||||
CIFSMaxBufSize, NULL, NULL);
|
||||
|
||||
if (rc)
|
||||
goto unlock;
|
||||
|
||||
/* If there's dirty data in the buffer that would extend the EOF if it
|
||||
* were written, then we need to move the EOF marker over to the lower
|
||||
* of the high end of the hole and the proposed EOF. The problem is
|
||||
* that we locally hole-punch the tail of the dirty data, the proposed
|
||||
* EOF update will end up in the wrong place.
|
||||
*/
|
||||
i_size = i_size_read(inode);
|
||||
remote_i_size = netfs_inode(inode)->remote_i_size;
|
||||
if (end > remote_i_size && i_size > remote_i_size) {
|
||||
unsigned long long extend_to = umin(end, i_size);
|
||||
rc = SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
|
||||
cfile->fid.volatile_fid, cfile->pid, extend_to);
|
||||
if (rc >= 0)
|
||||
netfs_inode(inode)->remote_i_size = extend_to;
|
||||
}
|
||||
|
||||
unlock:
|
||||
filemap_invalidate_unlock(inode->i_mapping);
|
||||
out:
|
||||
inode_unlock(inode);
|
||||
@ -4446,7 +4468,6 @@ smb3_init_transform_rq(struct TCP_Server_Info *server, int num_rqst,
|
||||
}
|
||||
iov_iter_xarray(&new->rq_iter, ITER_SOURCE,
|
||||
buffer, 0, size);
|
||||
new->rq_iter_size = size;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4492,7 +4513,6 @@ decrypt_raw_data(struct TCP_Server_Info *server, char *buf,
|
||||
rqst.rq_nvec = 2;
|
||||
if (iter) {
|
||||
rqst.rq_iter = *iter;
|
||||
rqst.rq_iter_size = iov_iter_count(iter);
|
||||
iter_size = iov_iter_count(iter);
|
||||
}
|
||||
|
||||
|
@ -4441,7 +4441,7 @@ smb2_new_read_req(void **buf, unsigned int *total_len,
|
||||
* If we want to do a RDMA write, fill in and append
|
||||
* smbd_buffer_descriptor_v1 to the end of read request
|
||||
*/
|
||||
if (smb3_use_rdma_offload(io_parms)) {
|
||||
if (rdata && smb3_use_rdma_offload(io_parms)) {
|
||||
struct smbd_buffer_descriptor_v1 *v1;
|
||||
bool need_invalidate = server->dialect == SMB30_PROT_ID;
|
||||
|
||||
@ -4523,7 +4523,6 @@ smb2_readv_callback(struct mid_q_entry *mid)
|
||||
|
||||
if (rdata->got_bytes) {
|
||||
rqst.rq_iter = rdata->subreq.io_iter;
|
||||
rqst.rq_iter_size = iov_iter_count(&rdata->subreq.io_iter);
|
||||
}
|
||||
|
||||
WARN_ONCE(rdata->server != mid->server,
|
||||
@ -4914,6 +4913,13 @@ smb2_async_writev(struct cifs_io_subrequest *wdata)
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
rqst.rq_iov = iov;
|
||||
rqst.rq_iter = wdata->subreq.io_iter;
|
||||
|
||||
rqst.rq_iov[0].iov_len = total_len - 1;
|
||||
rqst.rq_iov[0].iov_base = (char *)req;
|
||||
rqst.rq_nvec += 1;
|
||||
|
||||
if (smb3_encryption_required(tcon))
|
||||
flags |= CIFS_TRANSFORM_REQ;
|
||||
|
||||
@ -4925,6 +4931,7 @@ smb2_async_writev(struct cifs_io_subrequest *wdata)
|
||||
req->WriteChannelInfoOffset = 0;
|
||||
req->WriteChannelInfoLength = 0;
|
||||
req->Channel = SMB2_CHANNEL_NONE;
|
||||
req->Length = cpu_to_le32(io_parms->length);
|
||||
req->Offset = cpu_to_le64(io_parms->offset);
|
||||
req->DataOffset = cpu_to_le16(
|
||||
offsetof(struct smb2_write_req, Buffer));
|
||||
@ -4944,7 +4951,6 @@ smb2_async_writev(struct cifs_io_subrequest *wdata)
|
||||
*/
|
||||
if (smb3_use_rdma_offload(io_parms)) {
|
||||
struct smbd_buffer_descriptor_v1 *v1;
|
||||
size_t data_size = iov_iter_count(&wdata->subreq.io_iter);
|
||||
bool need_invalidate = server->dialect == SMB30_PROT_ID;
|
||||
|
||||
wdata->mr = smbd_register_mr(server->smbd_conn, &wdata->subreq.io_iter,
|
||||
@ -4953,9 +4959,10 @@ smb2_async_writev(struct cifs_io_subrequest *wdata)
|
||||
rc = -EAGAIN;
|
||||
goto async_writev_out;
|
||||
}
|
||||
/* For RDMA read, I/O size is in RemainingBytes not in Length */
|
||||
req->RemainingBytes = req->Length;
|
||||
req->Length = 0;
|
||||
req->DataOffset = 0;
|
||||
req->RemainingBytes = cpu_to_le32(data_size);
|
||||
req->Channel = SMB2_CHANNEL_RDMA_V1_INVALIDATE;
|
||||
if (need_invalidate)
|
||||
req->Channel = SMB2_CHANNEL_RDMA_V1;
|
||||
@ -4967,31 +4974,22 @@ smb2_async_writev(struct cifs_io_subrequest *wdata)
|
||||
v1->offset = cpu_to_le64(wdata->mr->mr->iova);
|
||||
v1->token = cpu_to_le32(wdata->mr->mr->rkey);
|
||||
v1->length = cpu_to_le32(wdata->mr->mr->length);
|
||||
|
||||
rqst.rq_iov[0].iov_len += sizeof(*v1);
|
||||
|
||||
/*
|
||||
* We keep wdata->subreq.io_iter,
|
||||
* but we have to truncate rqst.rq_iter
|
||||
*/
|
||||
iov_iter_truncate(&rqst.rq_iter, 0);
|
||||
}
|
||||
#endif
|
||||
iov[0].iov_len = total_len - 1;
|
||||
iov[0].iov_base = (char *)req;
|
||||
|
||||
rqst.rq_iov = iov;
|
||||
rqst.rq_nvec = 1;
|
||||
rqst.rq_iter = wdata->subreq.io_iter;
|
||||
rqst.rq_iter_size = iov_iter_count(&rqst.rq_iter);
|
||||
if (test_bit(NETFS_SREQ_RETRYING, &wdata->subreq.flags))
|
||||
smb2_set_replay(server, &rqst);
|
||||
#ifdef CONFIG_CIFS_SMB_DIRECT
|
||||
if (wdata->mr)
|
||||
iov[0].iov_len += sizeof(struct smbd_buffer_descriptor_v1);
|
||||
#endif
|
||||
cifs_dbg(FYI, "async write at %llu %u bytes iter=%zx\n",
|
||||
io_parms->offset, io_parms->length, iov_iter_count(&rqst.rq_iter));
|
||||
|
||||
#ifdef CONFIG_CIFS_SMB_DIRECT
|
||||
/* For RDMA read, I/O size is in RemainingBytes not in Length */
|
||||
if (!wdata->mr)
|
||||
req->Length = cpu_to_le32(io_parms->length);
|
||||
#else
|
||||
req->Length = cpu_to_le32(io_parms->length);
|
||||
#endif
|
||||
cifs_dbg(FYI, "async write at %llu %u bytes iter=%zx\n",
|
||||
io_parms->offset, io_parms->length, iov_iter_count(&wdata->subreq.io_iter));
|
||||
|
||||
if (wdata->credits.value > 0) {
|
||||
shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(wdata->subreq.len,
|
||||
|
Loading…
Reference in New Issue
Block a user