Message ID | 20180530194807.31657-4-longli@linuxonhyperv.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 5/30/2018 3:47 PM, Long Li wrote: > From: Long Li <longli@microsoft.com> > > With offset defined in rdata, transport functions need to look at this > offset when reading data into the correct places in pages. > > Signed-off-by: Long Li <longli@microsoft.com> > --- > fs/cifs/cifsproto.h | 4 +++- > fs/cifs/connect.c | 5 +++-- > fs/cifs/file.c | 52 +++++++++++++++++++++++++++++++++++++--------------- > fs/cifs/smb2ops.c | 2 +- > fs/cifs/smb2pdu.c | 1 + > 5 files changed, 45 insertions(+), 19 deletions(-) > > diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h > index dc80f84..1f27d8e 100644 > --- a/fs/cifs/cifsproto.h > +++ b/fs/cifs/cifsproto.h > @@ -203,7 +203,9 @@ extern void dequeue_mid(struct mid_q_entry *mid, bool malformed); > extern int cifs_read_from_socket(struct TCP_Server_Info *server, char *buf, > unsigned int to_read); > extern int cifs_read_page_from_socket(struct TCP_Server_Info *server, > - struct page *page, unsigned int to_read); > + struct page *page, > + unsigned int page_offset, > + unsigned int to_read); > extern int cifs_setup_cifs_sb(struct smb_vol *pvolume_info, > struct cifs_sb_info *cifs_sb); > extern int cifs_match_super(struct super_block *, void *); > diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c > index 83b0234..8501da0 100644 > --- a/fs/cifs/connect.c > +++ b/fs/cifs/connect.c > @@ -594,10 +594,11 @@ cifs_read_from_socket(struct TCP_Server_Info *server, char *buf, > > int > cifs_read_page_from_socket(struct TCP_Server_Info *server, struct page *page, > - unsigned int to_read) > + unsigned int page_offset, unsigned int to_read) > { > struct msghdr smb_msg; > - struct bio_vec bv = {.bv_page = page, .bv_len = to_read}; > + struct bio_vec bv = { > + .bv_page = page, .bv_len = to_read, .bv_offset = page_offset}; > iov_iter_bvec(&smb_msg.msg_iter, READ | ITER_BVEC, &bv, 1, to_read); > return cifs_readv_from_socket(server, &smb_msg); > } > diff --git a/fs/cifs/file.c b/fs/cifs/file.c > index 1c98293..87eece6 100644 > --- a/fs/cifs/file.c > +++ b/fs/cifs/file.c > @@ -3026,12 +3026,20 @@ uncached_fill_pages(struct TCP_Server_Info *server, > int result = 0; > unsigned int i; > unsigned int nr_pages = rdata->nr_pages; > + unsigned int page_offset = rdata->page_offset; > > rdata->got_bytes = 0; > rdata->tailsz = PAGE_SIZE; > for (i = 0; i < nr_pages; i++) { > struct page *page = rdata->pages[i]; > size_t n; > + unsigned int segment_size = rdata->pagesz; > + > + if (i == 0) > + segment_size -= page_offset; > + else > + page_offset = 0; > + > > if (len <= 0) { > /* no need to hold page hostage */ > @@ -3040,24 +3048,25 @@ uncached_fill_pages(struct TCP_Server_Info *server, > put_page(page); > continue; > } > + > n = len; > - if (len >= PAGE_SIZE) { > + if (len >= segment_size) > /* enough data to fill the page */ > - n = PAGE_SIZE; > - len -= n; > - } else { > - zero_user(page, len, PAGE_SIZE - len); > + n = segment_size; > + else > rdata->tailsz = len; > - len = 0; > - } > + len -= n; > + > if (iter) > - result = copy_page_from_iter(page, 0, n, iter); > + result = copy_page_from_iter( > + page, page_offset, n, iter); > #ifdef CONFIG_CIFS_SMB_DIRECT > else if (rdata->mr) > result = n; > #endif I hadn't noticed this type of xonditional code before. It's kind of ugly to modify the data handling code like this. Do you plan to break this out into an smbdirect-specific hander, like the cases above and below? > else > - result = cifs_read_page_from_socket(server, page, n); > + result = cifs_read_page_from_socket( > + server, page, page_offset, n); > if (result < 0) > break; > > @@ -3130,6 +3139,7 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file, > rdata->bytes = cur_len; > rdata->pid = pid; > rdata->pagesz = PAGE_SIZE; > + rdata->tailsz = PAGE_SIZE; > rdata->read_into_pages = cifs_uncached_read_into_pages; > rdata->copy_into_pages = cifs_uncached_copy_into_pages; > rdata->credits = credits; > @@ -3574,6 +3584,7 @@ readpages_fill_pages(struct TCP_Server_Info *server, > u64 eof; > pgoff_t eof_index; > unsigned int nr_pages = rdata->nr_pages; > + unsigned int page_offset = rdata->page_offset; > > /* determine the eof that the server (probably) has */ > eof = CIFS_I(rdata->mapping->host)->server_eof; > @@ -3584,13 +3595,21 @@ readpages_fill_pages(struct TCP_Server_Info *server, > rdata->tailsz = PAGE_SIZE; > for (i = 0; i < nr_pages; i++) { > struct page *page = rdata->pages[i]; > - size_t n = PAGE_SIZE; > + unsigned int to_read = rdata->pagesz; > + size_t n; > + > + if (i == 0) > + to_read -= page_offset; > + else > + page_offset = 0; > + > + n = to_read; > > - if (len >= PAGE_SIZE) { > - len -= PAGE_SIZE; > + if (len >= to_read) { > + len -= to_read; > } else if (len > 0) { > /* enough for partial page, fill and zero the rest */ > - zero_user(page, len, PAGE_SIZE - len); > + zero_user(page, len + page_offset, to_read - len); > n = rdata->tailsz = len; > len = 0; > } else if (page->index > eof_index) { > @@ -3622,13 +3641,15 @@ readpages_fill_pages(struct TCP_Server_Info *server, > } > > if (iter) > - result = copy_page_from_iter(page, 0, n, iter); > + result = copy_page_from_iter( > + page, page_offset, n, iter); > #ifdef CONFIG_CIFS_SMB_DIRECT > else if (rdata->mr) > result = n; > #endif Ditto previous comment/question. > else > - result = cifs_read_page_from_socket(server, page, n); > + result = cifs_read_page_from_socket( > + server, page, page_offset, n); > if (result < 0) > break; > > @@ -3807,6 +3828,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, > rdata->bytes = bytes; > rdata->pid = pid; > rdata->pagesz = PAGE_SIZE; > + rdata->tailsz = PAGE_SIZE; > rdata->read_into_pages = cifs_readpages_read_into_pages; > rdata->copy_into_pages = cifs_readpages_copy_into_pages; > rdata->credits = credits; > diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c > index 7c0edd2..1fa1c29 100644 > --- a/fs/cifs/smb2ops.c > +++ b/fs/cifs/smb2ops.c > @@ -2467,7 +2467,7 @@ read_data_into_pages(struct TCP_Server_Info *server, struct page **pages, > zero_user(page, len, PAGE_SIZE - len); > len = 0; > } > - length = cifs_read_page_from_socket(server, page, n); > + length = cifs_read_page_from_socket(server, page, 0, n); > if (length < 0) > return length; > server->total_read += length; > diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c > index a02f6b6..f603fbe 100644 > --- a/fs/cifs/smb2pdu.c > +++ b/fs/cifs/smb2pdu.c > @@ -2683,6 +2683,7 @@ smb2_readv_callback(struct mid_q_entry *mid) > struct smb_rqst rqst = { .rq_iov = rdata->iov, > .rq_nvec = 2, > .rq_pages = rdata->pages, > + .rq_offset = rdata->page_offset, > .rq_npages = rdata->nr_pages, > .rq_pagesz = rdata->pagesz, > .rq_tailsz = rdata->tailsz }; > -- To unsubscribe from this list: send the line "unsubscribe linux-cifs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
PiBGcm9tOiBUb20gVGFscGV5IDx0b21AdGFscGV5LmNvbT4NCj4gU2VudDogU2F0dXJkYXksIEp1 bmUgMjMsIDIwMTggNjo1OSBQTQ0KPiBUbzogTG9uZyBMaSA8bG9uZ2xpQG1pY3Jvc29mdC5jb20+ OyBTdGV2ZSBGcmVuY2ggPHNmcmVuY2hAc2FtYmEub3JnPjsNCj4gbGludXgtY2lmc0B2Z2VyLmtl cm5lbC5vcmc7IHNhbWJhLXRlY2huaWNhbEBsaXN0cy5zYW1iYS5vcmc7IGxpbnV4LQ0KPiBrZXJu ZWxAdmdlci5rZXJuZWwub3JnOyBsaW51eC1yZG1hQHZnZXIua2VybmVsLm9yZw0KPiBTdWJqZWN0 OiBSZTogW1BhdGNoIHYyIDAzLzE1XSBDSUZTOiBVc2Ugb2Zmc2V0IHdoZW4gcmVhZGluZyBwYWdl cw0KPiANCj4gT24gNS8zMC8yMDE4IDM6NDcgUE0sIExvbmcgTGkgd3JvdGU6DQo+ID4gRnJvbTog TG9uZyBMaSA8bG9uZ2xpQG1pY3Jvc29mdC5jb20+DQo+ID4NCj4gPiBXaXRoIG9mZnNldCBkZWZp bmVkIGluIHJkYXRhLCB0cmFuc3BvcnQgZnVuY3Rpb25zIG5lZWQgdG8gbG9vayBhdCB0aGlzDQo+ ID4gb2Zmc2V0IHdoZW4gcmVhZGluZyBkYXRhIGludG8gdGhlIGNvcnJlY3QgcGxhY2VzIGluIHBh Z2VzLg0KPiA+DQo+ID4gU2lnbmVkLW9mZi1ieTogTG9uZyBMaSA8bG9uZ2xpQG1pY3Jvc29mdC5j b20+DQo+ID4gLS0tDQo+ID4gICBmcy9jaWZzL2NpZnNwcm90by5oIHwgIDQgKysrLQ0KPiA+ICAg ZnMvY2lmcy9jb25uZWN0LmMgICB8ICA1ICsrKy0tDQo+ID4gICBmcy9jaWZzL2ZpbGUuYyAgICAg IHwgNTIgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKy0tLS0tLS0tDQo+IC0t LS0tLS0NCj4gPiAgIGZzL2NpZnMvc21iMm9wcy5jICAgfCAgMiArLQ0KPiA+ICAgZnMvY2lmcy9z bWIycGR1LmMgICB8ICAxICsNCj4gPiAgIDUgZmlsZXMgY2hhbmdlZCwgNDUgaW5zZXJ0aW9ucygr KSwgMTkgZGVsZXRpb25zKC0pDQo+ID4NCj4gPiBkaWZmIC0tZ2l0IGEvZnMvY2lmcy9jaWZzcHJv dG8uaCBiL2ZzL2NpZnMvY2lmc3Byb3RvLmggaW5kZXgNCj4gPiBkYzgwZjg0Li4xZjI3ZDhlIDEw MDY0NA0KPiA+IC0tLSBhL2ZzL2NpZnMvY2lmc3Byb3RvLmgNCj4gPiArKysgYi9mcy9jaWZzL2Np ZnNwcm90by5oDQo+ID4gQEAgLTIwMyw3ICsyMDMsOSBAQCBleHRlcm4gdm9pZCBkZXF1ZXVlX21p ZChzdHJ1Y3QgbWlkX3FfZW50cnkgKm1pZCwNCj4gYm9vbCBtYWxmb3JtZWQpOw0KPiA+ICAgZXh0 ZXJuIGludCBjaWZzX3JlYWRfZnJvbV9zb2NrZXQoc3RydWN0IFRDUF9TZXJ2ZXJfSW5mbyAqc2Vy dmVyLCBjaGFyDQo+ICpidWYsDQo+ID4gICAJCQkgICAgICAgICB1bnNpZ25lZCBpbnQgdG9fcmVh ZCk7DQo+ID4gICBleHRlcm4gaW50IGNpZnNfcmVhZF9wYWdlX2Zyb21fc29ja2V0KHN0cnVjdCBU Q1BfU2VydmVyX0luZm8gKnNlcnZlciwNCj4gPiAtCQkJCSAgICAgIHN0cnVjdCBwYWdlICpwYWdl LCB1bnNpZ25lZCBpbnQgdG9fcmVhZCk7DQo+ID4gKwkJCQkJc3RydWN0IHBhZ2UgKnBhZ2UsDQo+ ID4gKwkJCQkJdW5zaWduZWQgaW50IHBhZ2Vfb2Zmc2V0LA0KPiA+ICsJCQkJCXVuc2lnbmVkIGlu dCB0b19yZWFkKTsNCj4gPiAgIGV4dGVybiBpbnQgY2lmc19zZXR1cF9jaWZzX3NiKHN0cnVjdCBz bWJfdm9sICpwdm9sdW1lX2luZm8sDQo+ID4gICAJCQkgICAgICAgc3RydWN0IGNpZnNfc2JfaW5m byAqY2lmc19zYik7DQo+ID4gICBleHRlcm4gaW50IGNpZnNfbWF0Y2hfc3VwZXIoc3RydWN0IHN1 cGVyX2Jsb2NrICosIHZvaWQgKik7IGRpZmYNCj4gPiAtLWdpdCBhL2ZzL2NpZnMvY29ubmVjdC5j IGIvZnMvY2lmcy9jb25uZWN0LmMgaW5kZXggODNiMDIzNC4uODUwMWRhMA0KPiA+IDEwMDY0NA0K PiA+IC0tLSBhL2ZzL2NpZnMvY29ubmVjdC5jDQo+ID4gKysrIGIvZnMvY2lmcy9jb25uZWN0LmMN Cj4gPiBAQCAtNTk0LDEwICs1OTQsMTEgQEAgY2lmc19yZWFkX2Zyb21fc29ja2V0KHN0cnVjdCBU Q1BfU2VydmVyX0luZm8NCj4gPiAqc2VydmVyLCBjaGFyICpidWYsDQo+ID4NCj4gPiAgIGludA0K PiA+ICAgY2lmc19yZWFkX3BhZ2VfZnJvbV9zb2NrZXQoc3RydWN0IFRDUF9TZXJ2ZXJfSW5mbyAq c2VydmVyLCBzdHJ1Y3QgcGFnZQ0KPiAqcGFnZSwNCj4gPiAtCQkgICAgICB1bnNpZ25lZCBpbnQg dG9fcmVhZCkNCj4gPiArCXVuc2lnbmVkIGludCBwYWdlX29mZnNldCwgdW5zaWduZWQgaW50IHRv X3JlYWQpDQo+ID4gICB7DQo+ID4gICAJc3RydWN0IG1zZ2hkciBzbWJfbXNnOw0KPiA+IC0Jc3Ry dWN0IGJpb192ZWMgYnYgPSB7LmJ2X3BhZ2UgPSBwYWdlLCAuYnZfbGVuID0gdG9fcmVhZH07DQo+ ID4gKwlzdHJ1Y3QgYmlvX3ZlYyBidiA9IHsNCj4gPiArCQkuYnZfcGFnZSA9IHBhZ2UsIC5idl9s ZW4gPSB0b19yZWFkLCAuYnZfb2Zmc2V0ID0NCj4gcGFnZV9vZmZzZXR9Ow0KPiA+ICAgCWlvdl9p dGVyX2J2ZWMoJnNtYl9tc2cubXNnX2l0ZXIsIFJFQUQgfCBJVEVSX0JWRUMsICZidiwgMSwNCj4g dG9fcmVhZCk7DQo+ID4gICAJcmV0dXJuIGNpZnNfcmVhZHZfZnJvbV9zb2NrZXQoc2VydmVyLCAm c21iX21zZyk7DQo+ID4gICB9DQo+ID4gZGlmZiAtLWdpdCBhL2ZzL2NpZnMvZmlsZS5jIGIvZnMv Y2lmcy9maWxlLmMgaW5kZXggMWM5ODI5My4uODdlZWNlNg0KPiA+IDEwMDY0NA0KPiA+IC0tLSBh L2ZzL2NpZnMvZmlsZS5jDQo+ID4gKysrIGIvZnMvY2lmcy9maWxlLmMNCj4gPiBAQCAtMzAyNiwx MiArMzAyNiwyMCBAQCB1bmNhY2hlZF9maWxsX3BhZ2VzKHN0cnVjdCBUQ1BfU2VydmVyX0luZm8N Cj4gKnNlcnZlciwNCj4gPiAgIAlpbnQgcmVzdWx0ID0gMDsNCj4gPiAgIAl1bnNpZ25lZCBpbnQg aTsNCj4gPiAgIAl1bnNpZ25lZCBpbnQgbnJfcGFnZXMgPSByZGF0YS0+bnJfcGFnZXM7DQo+ID4g Kwl1bnNpZ25lZCBpbnQgcGFnZV9vZmZzZXQgPSByZGF0YS0+cGFnZV9vZmZzZXQ7DQo+ID4NCj4g PiAgIAlyZGF0YS0+Z290X2J5dGVzID0gMDsNCj4gPiAgIAlyZGF0YS0+dGFpbHN6ID0gUEFHRV9T SVpFOw0KPiA+ICAgCWZvciAoaSA9IDA7IGkgPCBucl9wYWdlczsgaSsrKSB7DQo+ID4gICAJCXN0 cnVjdCBwYWdlICpwYWdlID0gcmRhdGEtPnBhZ2VzW2ldOw0KPiA+ICAgCQlzaXplX3QgbjsNCj4g PiArCQl1bnNpZ25lZCBpbnQgc2VnbWVudF9zaXplID0gcmRhdGEtPnBhZ2VzejsNCj4gPiArDQo+ ID4gKwkJaWYgKGkgPT0gMCkNCj4gPiArCQkJc2VnbWVudF9zaXplIC09IHBhZ2Vfb2Zmc2V0Ow0K PiA+ICsJCWVsc2UNCj4gPiArCQkJcGFnZV9vZmZzZXQgPSAwOw0KPiA+ICsNCj4gPg0KPiA+ICAg CQlpZiAobGVuIDw9IDApIHsNCj4gPiAgIAkJCS8qIG5vIG5lZWQgdG8gaG9sZCBwYWdlIGhvc3Rh Z2UgKi8gQEAgLTMwNDAsMjQNCj4gKzMwNDgsMjUgQEANCj4gPiB1bmNhY2hlZF9maWxsX3BhZ2Vz KHN0cnVjdCBUQ1BfU2VydmVyX0luZm8gKnNlcnZlciwNCj4gPiAgIAkJCXB1dF9wYWdlKHBhZ2Up Ow0KPiA+ICAgCQkJY29udGludWU7DQo+ID4gICAJCX0NCj4gPiArDQo+ID4gICAJCW4gPSBsZW47 DQo+ID4gLQkJaWYgKGxlbiA+PSBQQUdFX1NJWkUpIHsNCj4gPiArCQlpZiAobGVuID49IHNlZ21l bnRfc2l6ZSkNCj4gPiAgIAkJCS8qIGVub3VnaCBkYXRhIHRvIGZpbGwgdGhlIHBhZ2UgKi8NCj4g PiAtCQkJbiA9IFBBR0VfU0laRTsNCj4gPiAtCQkJbGVuIC09IG47DQo+ID4gLQkJfSBlbHNlIHsN Cj4gPiAtCQkJemVyb191c2VyKHBhZ2UsIGxlbiwgUEFHRV9TSVpFIC0gbGVuKTsNCj4gPiArCQkJ biA9IHNlZ21lbnRfc2l6ZTsNCj4gPiArCQllbHNlDQo+ID4gICAJCQlyZGF0YS0+dGFpbHN6ID0g bGVuOw0KPiA+IC0JCQlsZW4gPSAwOw0KPiA+IC0JCX0NCj4gPiArCQlsZW4gLT0gbjsNCj4gPiAr DQo+ID4gICAJCWlmIChpdGVyKQ0KPiA+IC0JCQlyZXN1bHQgPSBjb3B5X3BhZ2VfZnJvbV9pdGVy KHBhZ2UsIDAsIG4sIGl0ZXIpOw0KPiA+ICsJCQlyZXN1bHQgPSBjb3B5X3BhZ2VfZnJvbV9pdGVy KA0KPiA+ICsJCQkJCXBhZ2UsIHBhZ2Vfb2Zmc2V0LCBuLCBpdGVyKTsNCj4gPiAgICNpZmRlZiBD T05GSUdfQ0lGU19TTUJfRElSRUNUDQo+ID4gICAJCWVsc2UgaWYgKHJkYXRhLT5tcikNCj4gPiAg IAkJCXJlc3VsdCA9IG47DQo+ID4gICAjZW5kaWYNCj4gDQo+IEkgaGFkbid0IG5vdGljZWQgdGhp cyB0eXBlIG9mIHhvbmRpdGlvbmFsIGNvZGUgYmVmb3JlLiBJdCdzIGtpbmQgb2YgdWdseSB0bw0K PiBtb2RpZnkgdGhlIGRhdGEgaGFuZGxpbmcgY29kZSBsaWtlIHRoaXMuIERvIHlvdSBwbGFuIHRv IGJyZWFrIHRoaXMgb3V0IGludG8gYW4NCj4gc21iZGlyZWN0LXNwZWNpZmljIGhhbmRlciwgbGlr ZSB0aGUgY2FzZXMgYWJvdmUgYW5kIGJlbG93Pw0KDQpUaGlzIGlzIGEgZ29vZCBwb2ludC4gSSB3 aWxsIGxvb2sgZm9yIHdheXMgdG8gaW1wcm92ZSB0aGlzLg0KDQo+IA0KPiA+ICAgCQllbHNlDQo+ ID4gLQkJCXJlc3VsdCA9IGNpZnNfcmVhZF9wYWdlX2Zyb21fc29ja2V0KHNlcnZlciwgcGFnZSwN Cj4gbik7DQo+ID4gKwkJCXJlc3VsdCA9IGNpZnNfcmVhZF9wYWdlX2Zyb21fc29ja2V0KA0KPiA+ ICsJCQkJCXNlcnZlciwgcGFnZSwgcGFnZV9vZmZzZXQsIG4pOw0KPiA+ICAgCQlpZiAocmVzdWx0 IDwgMCkNCj4gPiAgIAkJCWJyZWFrOw0KPiA+DQo+ID4gQEAgLTMxMzAsNiArMzEzOSw3IEBAIGNp ZnNfc2VuZF9hc3luY19yZWFkKGxvZmZfdCBvZmZzZXQsIHNpemVfdCBsZW4sDQo+IHN0cnVjdCBj aWZzRmlsZUluZm8gKm9wZW5fZmlsZSwNCj4gPiAgIAkJcmRhdGEtPmJ5dGVzID0gY3VyX2xlbjsN Cj4gPiAgIAkJcmRhdGEtPnBpZCA9IHBpZDsNCj4gPiAgIAkJcmRhdGEtPnBhZ2VzeiA9IFBBR0Vf U0laRTsNCj4gPiArCQlyZGF0YS0+dGFpbHN6ID0gUEFHRV9TSVpFOw0KPiA+ICAgCQlyZGF0YS0+ cmVhZF9pbnRvX3BhZ2VzID0gY2lmc191bmNhY2hlZF9yZWFkX2ludG9fcGFnZXM7DQo+ID4gICAJ CXJkYXRhLT5jb3B5X2ludG9fcGFnZXMgPSBjaWZzX3VuY2FjaGVkX2NvcHlfaW50b19wYWdlczsN Cj4gPiAgIAkJcmRhdGEtPmNyZWRpdHMgPSBjcmVkaXRzOw0KPiA+IEBAIC0zNTc0LDYgKzM1ODQs NyBAQCByZWFkcGFnZXNfZmlsbF9wYWdlcyhzdHJ1Y3QgVENQX1NlcnZlcl9JbmZvDQo+ICpzZXJ2 ZXIsDQo+ID4gICAJdTY0IGVvZjsNCj4gPiAgIAlwZ29mZl90IGVvZl9pbmRleDsNCj4gPiAgIAl1 bnNpZ25lZCBpbnQgbnJfcGFnZXMgPSByZGF0YS0+bnJfcGFnZXM7DQo+ID4gKwl1bnNpZ25lZCBp bnQgcGFnZV9vZmZzZXQgPSByZGF0YS0+cGFnZV9vZmZzZXQ7DQo+ID4NCj4gPiAgIAkvKiBkZXRl cm1pbmUgdGhlIGVvZiB0aGF0IHRoZSBzZXJ2ZXIgKHByb2JhYmx5KSBoYXMgKi8NCj4gPiAgIAll b2YgPSBDSUZTX0kocmRhdGEtPm1hcHBpbmctPmhvc3QpLT5zZXJ2ZXJfZW9mOw0KPiA+IEBAIC0z NTg0LDEzICszNTk1LDIxIEBAIHJlYWRwYWdlc19maWxsX3BhZ2VzKHN0cnVjdCBUQ1BfU2VydmVy X0luZm8NCj4gKnNlcnZlciwNCj4gPiAgIAlyZGF0YS0+dGFpbHN6ID0gUEFHRV9TSVpFOw0KPiA+ ICAgCWZvciAoaSA9IDA7IGkgPCBucl9wYWdlczsgaSsrKSB7DQo+ID4gICAJCXN0cnVjdCBwYWdl ICpwYWdlID0gcmRhdGEtPnBhZ2VzW2ldOw0KPiA+IC0JCXNpemVfdCBuID0gUEFHRV9TSVpFOw0K PiA+ICsJCXVuc2lnbmVkIGludCB0b19yZWFkID0gcmRhdGEtPnBhZ2VzejsNCj4gPiArCQlzaXpl X3QgbjsNCj4gPiArDQo+ID4gKwkJaWYgKGkgPT0gMCkNCj4gPiArCQkJdG9fcmVhZCAtPSBwYWdl X29mZnNldDsNCj4gPiArCQllbHNlDQo+ID4gKwkJCXBhZ2Vfb2Zmc2V0ID0gMDsNCj4gPiArDQo+ ID4gKwkJbiA9IHRvX3JlYWQ7DQo+ID4NCj4gPiAtCQlpZiAobGVuID49IFBBR0VfU0laRSkgew0K PiA+IC0JCQlsZW4gLT0gUEFHRV9TSVpFOw0KPiA+ICsJCWlmIChsZW4gPj0gdG9fcmVhZCkgew0K PiA+ICsJCQlsZW4gLT0gdG9fcmVhZDsNCj4gPiAgIAkJfSBlbHNlIGlmIChsZW4gPiAwKSB7DQo+ ID4gICAJCQkvKiBlbm91Z2ggZm9yIHBhcnRpYWwgcGFnZSwgZmlsbCBhbmQgemVybyB0aGUgcmVz dCAqLw0KPiA+IC0JCQl6ZXJvX3VzZXIocGFnZSwgbGVuLCBQQUdFX1NJWkUgLSBsZW4pOw0KPiA+ ICsJCQl6ZXJvX3VzZXIocGFnZSwgbGVuICsgcGFnZV9vZmZzZXQsIHRvX3JlYWQgLSBsZW4pOw0K PiA+ICAgCQkJbiA9IHJkYXRhLT50YWlsc3ogPSBsZW47DQo+ID4gICAJCQlsZW4gPSAwOw0KPiA+ ICAgCQl9IGVsc2UgaWYgKHBhZ2UtPmluZGV4ID4gZW9mX2luZGV4KSB7IEBAIC0zNjIyLDEzICsz NjQxLDE1DQo+IEBADQo+ID4gcmVhZHBhZ2VzX2ZpbGxfcGFnZXMoc3RydWN0IFRDUF9TZXJ2ZXJf SW5mbyAqc2VydmVyLA0KPiA+ICAgCQl9DQo+ID4NCj4gPiAgIAkJaWYgKGl0ZXIpDQo+ID4gLQkJ CXJlc3VsdCA9IGNvcHlfcGFnZV9mcm9tX2l0ZXIocGFnZSwgMCwgbiwgaXRlcik7DQo+ID4gKwkJ CXJlc3VsdCA9IGNvcHlfcGFnZV9mcm9tX2l0ZXIoDQo+ID4gKwkJCQkJcGFnZSwgcGFnZV9vZmZz ZXQsIG4sIGl0ZXIpOw0KPiA+ICAgI2lmZGVmIENPTkZJR19DSUZTX1NNQl9ESVJFQ1QNCj4gPiAg IAkJZWxzZSBpZiAocmRhdGEtPm1yKQ0KPiA+ICAgCQkJcmVzdWx0ID0gbjsNCj4gPiAgICNlbmRp Zg0KPiANCj4gRGl0dG8gcHJldmlvdXMgY29tbWVudC9xdWVzdGlvbi4NCj4gDQo+ID4gICAJCWVs c2UNCj4gPiAtCQkJcmVzdWx0ID0gY2lmc19yZWFkX3BhZ2VfZnJvbV9zb2NrZXQoc2VydmVyLCBw YWdlLA0KPiBuKTsNCj4gPiArCQkJcmVzdWx0ID0gY2lmc19yZWFkX3BhZ2VfZnJvbV9zb2NrZXQo DQo+ID4gKwkJCQkJc2VydmVyLCBwYWdlLCBwYWdlX29mZnNldCwgbik7DQo+ID4gICAJCWlmIChy ZXN1bHQgPCAwKQ0KPiA+ICAgCQkJYnJlYWs7DQo+ID4NCj4gPiBAQCAtMzgwNyw2ICszODI4LDcg QEAgc3RhdGljIGludCBjaWZzX3JlYWRwYWdlcyhzdHJ1Y3QgZmlsZSAqZmlsZSwgc3RydWN0DQo+ IGFkZHJlc3Nfc3BhY2UgKm1hcHBpbmcsDQo+ID4gICAJCXJkYXRhLT5ieXRlcyA9IGJ5dGVzOw0K PiA+ICAgCQlyZGF0YS0+cGlkID0gcGlkOw0KPiA+ICAgCQlyZGF0YS0+cGFnZXN6ID0gUEFHRV9T SVpFOw0KPiA+ICsJCXJkYXRhLT50YWlsc3ogPSBQQUdFX1NJWkU7DQo+ID4gICAJCXJkYXRhLT5y ZWFkX2ludG9fcGFnZXMgPSBjaWZzX3JlYWRwYWdlc19yZWFkX2ludG9fcGFnZXM7DQo+ID4gICAJ CXJkYXRhLT5jb3B5X2ludG9fcGFnZXMgPSBjaWZzX3JlYWRwYWdlc19jb3B5X2ludG9fcGFnZXM7 DQo+ID4gICAJCXJkYXRhLT5jcmVkaXRzID0gY3JlZGl0czsNCj4gPiBkaWZmIC0tZ2l0IGEvZnMv Y2lmcy9zbWIyb3BzLmMgYi9mcy9jaWZzL3NtYjJvcHMuYyBpbmRleA0KPiA+IDdjMGVkZDIuLjFm YTFjMjkgMTAwNjQ0DQo+ID4gLS0tIGEvZnMvY2lmcy9zbWIyb3BzLmMNCj4gPiArKysgYi9mcy9j aWZzL3NtYjJvcHMuYw0KPiA+IEBAIC0yNDY3LDcgKzI0NjcsNyBAQCByZWFkX2RhdGFfaW50b19w YWdlcyhzdHJ1Y3QgVENQX1NlcnZlcl9JbmZvDQo+ICpzZXJ2ZXIsIHN0cnVjdCBwYWdlICoqcGFn ZXMsDQo+ID4gICAJCQl6ZXJvX3VzZXIocGFnZSwgbGVuLCBQQUdFX1NJWkUgLSBsZW4pOw0KPiA+ ICAgCQkJbGVuID0gMDsNCj4gPiAgIAkJfQ0KPiA+IC0JCWxlbmd0aCA9IGNpZnNfcmVhZF9wYWdl X2Zyb21fc29ja2V0KHNlcnZlciwgcGFnZSwgbik7DQo+ID4gKwkJbGVuZ3RoID0gY2lmc19yZWFk X3BhZ2VfZnJvbV9zb2NrZXQoc2VydmVyLCBwYWdlLCAwLCBuKTsNCj4gPiAgIAkJaWYgKGxlbmd0 aCA8IDApDQo+ID4gICAJCQlyZXR1cm4gbGVuZ3RoOw0KPiA+ICAgCQlzZXJ2ZXItPnRvdGFsX3Jl YWQgKz0gbGVuZ3RoOw0KPiA+IGRpZmYgLS1naXQgYS9mcy9jaWZzL3NtYjJwZHUuYyBiL2ZzL2Np ZnMvc21iMnBkdS5jIGluZGV4DQo+ID4gYTAyZjZiNi4uZjYwM2ZiZSAxMDA2NDQNCj4gPiAtLS0g YS9mcy9jaWZzL3NtYjJwZHUuYw0KPiA+ICsrKyBiL2ZzL2NpZnMvc21iMnBkdS5jDQo+ID4gQEAg LTI2ODMsNiArMjY4Myw3IEBAIHNtYjJfcmVhZHZfY2FsbGJhY2soc3RydWN0IG1pZF9xX2VudHJ5 ICptaWQpDQo+ID4gICAJc3RydWN0IHNtYl9ycXN0IHJxc3QgPSB7IC5ycV9pb3YgPSByZGF0YS0+ aW92LA0KPiA+ICAgCQkJCSAucnFfbnZlYyA9IDIsDQo+ID4gICAJCQkJIC5ycV9wYWdlcyA9IHJk YXRhLT5wYWdlcywNCj4gPiArCQkJCSAucnFfb2Zmc2V0ID0gcmRhdGEtPnBhZ2Vfb2Zmc2V0LA0K PiA+ICAgCQkJCSAucnFfbnBhZ2VzID0gcmRhdGEtPm5yX3BhZ2VzLA0KPiA+ICAgCQkJCSAucnFf cGFnZXN6ID0gcmRhdGEtPnBhZ2VzeiwNCj4gPiAgIAkJCQkgLnJxX3RhaWxzeiA9IHJkYXRhLT50 YWlsc3ogfTsNCj4gPg0K -- To unsubscribe from this list: send the line "unsubscribe linux-cifs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index dc80f84..1f27d8e 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -203,7 +203,9 @@ extern void dequeue_mid(struct mid_q_entry *mid, bool malformed); extern int cifs_read_from_socket(struct TCP_Server_Info *server, char *buf, unsigned int to_read); extern int cifs_read_page_from_socket(struct TCP_Server_Info *server, - struct page *page, unsigned int to_read); + struct page *page, + unsigned int page_offset, + unsigned int to_read); extern int cifs_setup_cifs_sb(struct smb_vol *pvolume_info, struct cifs_sb_info *cifs_sb); extern int cifs_match_super(struct super_block *, void *); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 83b0234..8501da0 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -594,10 +594,11 @@ cifs_read_from_socket(struct TCP_Server_Info *server, char *buf, int cifs_read_page_from_socket(struct TCP_Server_Info *server, struct page *page, - unsigned int to_read) + unsigned int page_offset, unsigned int to_read) { struct msghdr smb_msg; - struct bio_vec bv = {.bv_page = page, .bv_len = to_read}; + struct bio_vec bv = { + .bv_page = page, .bv_len = to_read, .bv_offset = page_offset}; iov_iter_bvec(&smb_msg.msg_iter, READ | ITER_BVEC, &bv, 1, to_read); return cifs_readv_from_socket(server, &smb_msg); } diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 1c98293..87eece6 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -3026,12 +3026,20 @@ uncached_fill_pages(struct TCP_Server_Info *server, int result = 0; unsigned int i; unsigned int nr_pages = rdata->nr_pages; + unsigned int page_offset = rdata->page_offset; rdata->got_bytes = 0; rdata->tailsz = PAGE_SIZE; for (i = 0; i < nr_pages; i++) { struct page *page = rdata->pages[i]; size_t n; + unsigned int segment_size = rdata->pagesz; + + if (i == 0) + segment_size -= page_offset; + else + page_offset = 0; + if (len <= 0) { /* no need to hold page hostage */ @@ -3040,24 +3048,25 @@ uncached_fill_pages(struct TCP_Server_Info *server, put_page(page); continue; } + n = len; - if (len >= PAGE_SIZE) { + if (len >= segment_size) /* enough data to fill the page */ - n = PAGE_SIZE; - len -= n; - } else { - zero_user(page, len, PAGE_SIZE - len); + n = segment_size; + else rdata->tailsz = len; - len = 0; - } + len -= n; + if (iter) - result = copy_page_from_iter(page, 0, n, iter); + result = copy_page_from_iter( + page, page_offset, n, iter); #ifdef CONFIG_CIFS_SMB_DIRECT else if (rdata->mr) result = n; #endif else - result = cifs_read_page_from_socket(server, page, n); + result = cifs_read_page_from_socket( + server, page, page_offset, n); if (result < 0) break; @@ -3130,6 +3139,7 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file, rdata->bytes = cur_len; rdata->pid = pid; rdata->pagesz = PAGE_SIZE; + rdata->tailsz = PAGE_SIZE; rdata->read_into_pages = cifs_uncached_read_into_pages; rdata->copy_into_pages = cifs_uncached_copy_into_pages; rdata->credits = credits; @@ -3574,6 +3584,7 @@ readpages_fill_pages(struct TCP_Server_Info *server, u64 eof; pgoff_t eof_index; unsigned int nr_pages = rdata->nr_pages; + unsigned int page_offset = rdata->page_offset; /* determine the eof that the server (probably) has */ eof = CIFS_I(rdata->mapping->host)->server_eof; @@ -3584,13 +3595,21 @@ readpages_fill_pages(struct TCP_Server_Info *server, rdata->tailsz = PAGE_SIZE; for (i = 0; i < nr_pages; i++) { struct page *page = rdata->pages[i]; - size_t n = PAGE_SIZE; + unsigned int to_read = rdata->pagesz; + size_t n; + + if (i == 0) + to_read -= page_offset; + else + page_offset = 0; + + n = to_read; - if (len >= PAGE_SIZE) { - len -= PAGE_SIZE; + if (len >= to_read) { + len -= to_read; } else if (len > 0) { /* enough for partial page, fill and zero the rest */ - zero_user(page, len, PAGE_SIZE - len); + zero_user(page, len + page_offset, to_read - len); n = rdata->tailsz = len; len = 0; } else if (page->index > eof_index) { @@ -3622,13 +3641,15 @@ readpages_fill_pages(struct TCP_Server_Info *server, } if (iter) - result = copy_page_from_iter(page, 0, n, iter); + result = copy_page_from_iter( + page, page_offset, n, iter); #ifdef CONFIG_CIFS_SMB_DIRECT else if (rdata->mr) result = n; #endif else - result = cifs_read_page_from_socket(server, page, n); + result = cifs_read_page_from_socket( + server, page, page_offset, n); if (result < 0) break; @@ -3807,6 +3828,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, rdata->bytes = bytes; rdata->pid = pid; rdata->pagesz = PAGE_SIZE; + rdata->tailsz = PAGE_SIZE; rdata->read_into_pages = cifs_readpages_read_into_pages; rdata->copy_into_pages = cifs_readpages_copy_into_pages; rdata->credits = credits; diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 7c0edd2..1fa1c29 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -2467,7 +2467,7 @@ read_data_into_pages(struct TCP_Server_Info *server, struct page **pages, zero_user(page, len, PAGE_SIZE - len); len = 0; } - length = cifs_read_page_from_socket(server, page, n); + length = cifs_read_page_from_socket(server, page, 0, n); if (length < 0) return length; server->total_read += length; diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index a02f6b6..f603fbe 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -2683,6 +2683,7 @@ smb2_readv_callback(struct mid_q_entry *mid) struct smb_rqst rqst = { .rq_iov = rdata->iov, .rq_nvec = 2, .rq_pages = rdata->pages, + .rq_offset = rdata->page_offset, .rq_npages = rdata->nr_pages, .rq_pagesz = rdata->pagesz, .rq_tailsz = rdata->tailsz };