From: Trond Myklebust <trond.myklebust@fys.uio.no> --=-O2aAqp6DrzPwP3KoW56V Content-Type: text/plain Content-Transfer-Encoding: 7bit NFSv2/v3/v4: Patch by Chuck Lever that add support for asynchronous reads even if rsize<PAGE_CACHE_SIZE. Cheers, Trond --=-O2aAqp6DrzPwP3KoW56V Content-Disposition: attachment; filename=linux-2.6.4-02-small_rsize.dif Content-Type: text/plain; name=linux-2.6.4-02-small_rsize.dif; charset=ISO-8859-1 Content-Transfer-Encoding: base64 IGZzL25mcy9kaXJlY3QuYyAgICAgICAgIHwgICAgMQ0KIGZzL25mcy9uZnMzcHJvYy5jICAgICAg IHwgICAyMSAtLS0NCiBmcy9uZnMvbmZzNHByb2MuYyAgICAgICB8ICAgNDEgLS0tLS0NCiBmcy9u ZnMvbmZzNHhkci5jICAgICAgICB8ICAgMjIgKystDQogZnMvbmZzL3Byb2MuYyAgICAgICAgICAg fCAgIDIxIC0tLQ0KIGZzL25mcy9yZWFkLmMgICAgICAgICAgIHwgIDMzMSArKysrKysrKysrKysr KysrKysrKysrKysrKysrKysrKysrKystLS0tLS0tLS0tLS0NCiBpbmNsdWRlL2xpbnV4L25mc19m cy5oICB8ICAgIDENCiBpbmNsdWRlL2xpbnV4L25mc194ZHIuaCB8ICAgIDYNCiA4IGZpbGVzIGNo YW5nZWQsIDI4OCBpbnNlcnRpb25zKCspLCAxNTYgZGVsZXRpb25zKC0pDQoNCmRpZmYgLXUgLS1y ZWN1cnNpdmUgLS1uZXctZmlsZSAtLXNob3ctYy1mdW5jdGlvbiBsaW51eC0yLjYuMy0xOS1wcmVw YXJlX25mc3BhZ2UvZnMvbmZzL2RpcmVjdC5jIGxpbnV4LTIuNi4zLTIwLXNtYWxsX3JzaXplL2Zz L25mcy9kaXJlY3QuYw0KLS0tIGxpbnV4LTIuNi4zLTE5LXByZXBhcmVfbmZzcGFnZS9mcy9uZnMv ZGlyZWN0LmMJMjAwNC0wMy0wMSAxOTozODoyOS4wMDAwMDAwMDAgLTA1MDANCisrKyBsaW51eC0y LjYuMy0yMC1zbWFsbF9yc2l6ZS9mcy9uZnMvZGlyZWN0LmMJMjAwNC0wMy0wMSAxOTo0MTowNi4w MDAwMDAwMDAgLTA1MDANCkBAIC0xMjgsNiArMTI4LDcgQEAgbmZzX2RpcmVjdF9yZWFkX3NlZyhz dHJ1Y3QgaW5vZGUgKmlub2RlLA0KIAkJLmlub2RlCQk9IGlub2RlLA0KIAkJLmFyZ3MJCT0gew0K IAkJCS5maAkJPSBORlNfRkgoaW5vZGUpLA0KKwkJCS5sb2Nrb3duZXIJPSBjdXJyZW50LT5maWxl cywNCiAJCX0sDQogCQkucmVzCQk9IHsNCiAJCQkuZmF0dHIJCT0gJnJkYXRhLmZhdHRyLA0KZGlm ZiAtdSAtLXJlY3Vyc2l2ZSAtLW5ldy1maWxlIC0tc2hvdy1jLWZ1bmN0aW9uIGxpbnV4LTIuNi4z LTE5LXByZXBhcmVfbmZzcGFnZS9mcy9uZnMvbmZzM3Byb2MuYyBsaW51eC0yLjYuMy0yMC1zbWFs bF9yc2l6ZS9mcy9uZnMvbmZzM3Byb2MuYw0KLS0tIGxpbnV4LTIuNi4zLTE5LXByZXBhcmVfbmZz cGFnZS9mcy9uZnMvbmZzM3Byb2MuYwkyMDA0LTAzLTAxIDE5OjM4OjQ3LjAwMDAwMDAwMCAtMDUw MA0KKysrIGxpbnV4LTIuNi4zLTIwLXNtYWxsX3JzaXplL2ZzL25mcy9uZnMzcHJvYy5jCTIwMDQt MDMtMDEgMTk6NDE6MDYuMDAwMDAwMDAwIC0wNTAwDQpAQCAtNzI5LDExICs3MjksMTAgQEAgbmZz M19yZWFkX2RvbmUoc3RydWN0IHJwY190YXNrICp0YXNrKQ0KIH0NCiANCiBzdGF0aWMgdm9pZA0K LW5mczNfcHJvY19yZWFkX3NldHVwKHN0cnVjdCBuZnNfcmVhZF9kYXRhICpkYXRhLCB1bnNpZ25l ZCBpbnQgY291bnQpDQorbmZzM19wcm9jX3JlYWRfc2V0dXAoc3RydWN0IG5mc19yZWFkX2RhdGEg KmRhdGEpDQogew0KIAlzdHJ1Y3QgcnBjX3Rhc2sJCSp0YXNrID0gJmRhdGEtPnRhc2s7DQogCXN0 cnVjdCBpbm9kZQkJKmlub2RlID0gZGF0YS0+aW5vZGU7DQotCXN0cnVjdCBuZnNfcGFnZQkJKnJl cTsNCiAJaW50CQkJZmxhZ3M7DQogCXN0cnVjdCBycGNfbWVzc2FnZQltc2cgPSB7DQogCQkucnBj X3Byb2MJPSAmbmZzM19wcm9jZWR1cmVzW05GUzNQUk9DX1JFQURdLA0KQEAgLTc0MSwyNyArNzQw LDEzIEBAIG5mczNfcHJvY19yZWFkX3NldHVwKHN0cnVjdCBuZnNfcmVhZF9kYXQNCiAJCS5ycGNf cmVzcAk9ICZkYXRhLT5yZXMsDQogCQkucnBjX2NyZWQJPSBkYXRhLT5jcmVkLA0KIAl9Ow0KLQkN Ci0JcmVxID0gbmZzX2xpc3RfZW50cnkoZGF0YS0+cGFnZXMubmV4dCk7DQotCWRhdGEtPmFyZ3Mu ZmggICAgID0gTkZTX0ZIKGlub2RlKTsNCi0JZGF0YS0+YXJncy5vZmZzZXQgPSByZXFfb2Zmc2V0 KHJlcSk7DQotCWRhdGEtPmFyZ3MucGdiYXNlID0gcmVxLT53Yl9wZ2Jhc2U7DQotCWRhdGEtPmFy Z3MucGFnZXMgID0gZGF0YS0+cGFnZXZlYzsNCi0JZGF0YS0+YXJncy5jb3VudCAgPSBjb3VudDsN Ci0JZGF0YS0+cmVzLmZhdHRyICAgPSAmZGF0YS0+ZmF0dHI7DQotCWRhdGEtPnJlcy5jb3VudCAg ID0gY291bnQ7DQotCWRhdGEtPnJlcy5lb2YgICAgID0gMDsNCi0JDQorDQogCS8qIE4uQi4gRG8g d2UgbmVlZCB0byB0ZXN0PyBOZXZlciBjYWxsZWQgZm9yIHN3YXBmaWxlIGlub2RlICovDQogCWZs YWdzID0gUlBDX1RBU0tfQVNZTkMgfCAoSVNfU1dBUEZJTEUoaW5vZGUpPyBORlNfUlBDX1NXQVBG TEFHUyA6IDApOw0KIA0KIAkvKiBGaW5hbGl6ZSB0aGUgdGFzay4gKi8NCiAJcnBjX2luaXRfdGFz ayh0YXNrLCBORlNfQ0xJRU5UKGlub2RlKSwgbmZzM19yZWFkX2RvbmUsIGZsYWdzKTsNCi0JdGFz ay0+dGtfY2FsbGRhdGEgPSBkYXRhOw0KLQkvKiBSZWxlYXNlIHJlcXVlc3RzICovDQotCXRhc2st PnRrX3JlbGVhc2UgPSBuZnNfcmVhZGRhdGFfcmVsZWFzZTsNCi0NCi0JcnBjX2NhbGxfc2V0dXAo JmRhdGEtPnRhc2ssICZtc2csIDApOw0KKwlycGNfY2FsbF9zZXR1cCh0YXNrLCAmbXNnLCAwKTsN CiB9DQogDQogc3RhdGljIHZvaWQNCmRpZmYgLXUgLS1yZWN1cnNpdmUgLS1uZXctZmlsZSAtLXNo b3ctYy1mdW5jdGlvbiBsaW51eC0yLjYuMy0xOS1wcmVwYXJlX25mc3BhZ2UvZnMvbmZzL25mczRw cm9jLmMgbGludXgtMi42LjMtMjAtc21hbGxfcnNpemUvZnMvbmZzL25mczRwcm9jLmMNCi0tLSBs aW51eC0yLjYuMy0xOS1wcmVwYXJlX25mc3BhZ2UvZnMvbmZzL25mczRwcm9jLmMJMjAwNC0wMy0w MSAxOTozOTozMi4wMDAwMDAwMDAgLTA1MDANCisrKyBsaW51eC0yLjYuMy0yMC1zbWFsbF9yc2l6 ZS9mcy9uZnMvbmZzNHByb2MuYwkyMDA0LTAzLTAxIDE5OjQxOjA2LjAwMDAwMDAwMCAtMDUwMA0K QEAgLTEwODUsMTAgKzEwODUsMTAgQEAgbmZzNF9wcm9jX3JlYWQoc3RydWN0IG5mc19yZWFkX2Rh dGEgKnJkYQ0KIAlpZiAoZmlscCkgew0KIAkJc3RydWN0IG5mczRfc3RhdGUgKnN0YXRlOw0KIAkJ c3RhdGUgPSAoc3RydWN0IG5mczRfc3RhdGUgKilmaWxwLT5wcml2YXRlX2RhdGE7DQotCQluZnM0 X2NvcHlfc3RhdGVpZCgmcmRhdGEtPmFyZ3Muc3RhdGVpZCwgc3RhdGUsIHJkYXRhLT5sb2Nrb3du ZXIpOw0KKwkJcmRhdGEtPmFyZ3Muc3RhdGUgPSBzdGF0ZTsNCiAJCW1zZy5ycGNfY3JlZCA9IHN0 YXRlLT5vd25lci0+c29fY3JlZDsNCiAJfSBlbHNlIHsNCi0JCW1lbWNweSgmcmRhdGEtPmFyZ3Mu c3RhdGVpZCwgJnplcm9fc3RhdGVpZCwgc2l6ZW9mKHJkYXRhLT5hcmdzLnN0YXRlaWQpKTsNCisJ CXJkYXRhLT5hcmdzLnN0YXRlID0gTlVMTDsNCiAJCW1zZy5ycGNfY3JlZCA9IE5GU19JKGlub2Rl KS0+bW1fY3JlZDsNCiAJfQ0KIA0KQEAgLTE0OTksMjcgKzE0OTksMTMgQEAgbmZzNF9wcm9jX3Bh dGhjb25mKHN0cnVjdCBuZnNfc2VydmVyICpzZQ0KIH0NCiANCiBzdGF0aWMgdm9pZA0KLW5mczRf cmVzdGFydF9yZWFkKHN0cnVjdCBycGNfdGFzayAqdGFzaykNCi17DQotCXN0cnVjdCBuZnNfcmVh ZF9kYXRhICpkYXRhID0gKHN0cnVjdCBuZnNfcmVhZF9kYXRhICopdGFzay0+dGtfY2FsbGRhdGE7 DQotCXN0cnVjdCBuZnNfcGFnZSAqcmVxOw0KLQ0KLQlycGNfcmVzdGFydF9jYWxsKHRhc2spOw0K LQlyZXEgPSBuZnNfbGlzdF9lbnRyeShkYXRhLT5wYWdlcy5uZXh0KTsNCi0JaWYgKHJlcS0+d2Jf c3RhdGUpDQotCQluZnM0X2NvcHlfc3RhdGVpZCgmZGF0YS0+YXJncy5zdGF0ZWlkLCByZXEtPndi X3N0YXRlLCByZXEtPndiX2xvY2tvd25lcik7DQotCWVsc2UNCi0JCW1lbWNweSgmZGF0YS0+YXJn cy5zdGF0ZWlkLCAmemVyb19zdGF0ZWlkLCBzaXplb2YoZGF0YS0+YXJncy5zdGF0ZWlkKSk7DQot fQ0KLQ0KLXN0YXRpYyB2b2lkDQogbmZzNF9yZWFkX2RvbmUoc3RydWN0IHJwY190YXNrICp0YXNr KQ0KIHsNCiAJc3RydWN0IG5mc19yZWFkX2RhdGEgKmRhdGEgPSAoc3RydWN0IG5mc19yZWFkX2Rh dGEgKikgdGFzay0+dGtfY2FsbGRhdGE7DQogCXN0cnVjdCBpbm9kZSAqaW5vZGUgPSBkYXRhLT5p bm9kZTsNCiANCiAJaWYgKG5mczRfYXN5bmNfaGFuZGxlX2Vycm9yKHRhc2ssIE5GU19TRVJWRVIo aW5vZGUpKSA9PSAtRUFHQUlOKSB7DQotCQl0YXNrLT50a19hY3Rpb24gPSBuZnM0X3Jlc3RhcnRf cmVhZDsNCisJCXJwY19yZXN0YXJ0X2NhbGwodGFzayk7DQogCQlyZXR1cm47DQogCX0NCiAJaWYg KHRhc2stPnRrX3N0YXR1cyA+IDApDQpAQCAtMTUyOSw3ICsxNTE1LDcgQEAgbmZzNF9yZWFkX2Rv bmUoc3RydWN0IHJwY190YXNrICp0YXNrKQ0KIH0NCiANCiBzdGF0aWMgdm9pZA0KLW5mczRfcHJv Y19yZWFkX3NldHVwKHN0cnVjdCBuZnNfcmVhZF9kYXRhICpkYXRhLCB1bnNpZ25lZCBpbnQgY291 bnQpDQorbmZzNF9wcm9jX3JlYWRfc2V0dXAoc3RydWN0IG5mc19yZWFkX2RhdGEgKmRhdGEpDQog ew0KIAlzdHJ1Y3QgcnBjX3Rhc2sJKnRhc2sgPSAmZGF0YS0+dGFzazsNCiAJc3RydWN0IHJwY19t ZXNzYWdlIG1zZyA9IHsNCkBAIC0xNTM5LDM0ICsxNTI1LDE1IEBAIG5mczRfcHJvY19yZWFkX3Nl dHVwKHN0cnVjdCBuZnNfcmVhZF9kYXQNCiAJCS5ycGNfY3JlZCA9IGRhdGEtPmNyZWQsDQogCX07 DQogCXN0cnVjdCBpbm9kZSAqaW5vZGUgPSBkYXRhLT5pbm9kZTsNCi0Jc3RydWN0IG5mc19wYWdl ICpyZXEgPSBuZnNfbGlzdF9lbnRyeShkYXRhLT5wYWdlcy5uZXh0KTsNCiAJaW50IGZsYWdzOw0K IA0KLQlkYXRhLT5hcmdzLmZoICAgICA9IE5GU19GSChpbm9kZSk7DQotCWRhdGEtPmFyZ3Mub2Zm c2V0ID0gcmVxX29mZnNldChyZXEpOw0KLQlkYXRhLT5hcmdzLnBnYmFzZSA9IHJlcS0+d2JfcGdi YXNlOw0KLQlkYXRhLT5hcmdzLnBhZ2VzICA9IGRhdGEtPnBhZ2V2ZWM7DQotCWRhdGEtPmFyZ3Mu Y291bnQgID0gY291bnQ7DQotCWRhdGEtPnJlcy5mYXR0ciAgID0gJmRhdGEtPmZhdHRyOw0KLQlk YXRhLT5yZXMuY291bnQgICA9IGNvdW50Ow0KLQlkYXRhLT5yZXMuZW9mICAgICA9IDA7DQogCWRh dGEtPnRpbWVzdGFtcCAgID0gamlmZmllczsNCiANCi0JZGF0YS0+bG9ja293bmVyID0gcmVxLT53 Yl9sb2Nrb3duZXI7DQotCWlmIChyZXEtPndiX3N0YXRlKQ0KLQkJbmZzNF9jb3B5X3N0YXRlaWQo JmRhdGEtPmFyZ3Muc3RhdGVpZCwgcmVxLT53Yl9zdGF0ZSwgcmVxLT53Yl9sb2Nrb3duZXIpOw0K LQllbHNlDQotCQltZW1jcHkoJmRhdGEtPmFyZ3Muc3RhdGVpZCwgJnplcm9fc3RhdGVpZCwgc2l6 ZW9mKGRhdGEtPmFyZ3Muc3RhdGVpZCkpOw0KLQ0KIAkvKiBOLkIuIERvIHdlIG5lZWQgdG8gdGVz dD8gTmV2ZXIgY2FsbGVkIGZvciBzd2FwZmlsZSBpbm9kZSAqLw0KIAlmbGFncyA9IFJQQ19UQVNL X0FTWU5DIHwgKElTX1NXQVBGSUxFKGlub2RlKT8gTkZTX1JQQ19TV0FQRkxBR1MgOiAwKTsNCiAN CiAJLyogRmluYWxpemUgdGhlIHRhc2suICovDQogCXJwY19pbml0X3Rhc2sodGFzaywgTkZTX0NM SUVOVChpbm9kZSksIG5mczRfcmVhZF9kb25lLCBmbGFncyk7DQotCXRhc2stPnRrX2NhbGxkYXRh ID0gZGF0YTsNCi0JLyogUmVsZWFzZSByZXF1ZXN0cyAqLw0KLQl0YXNrLT50a19yZWxlYXNlID0g bmZzX3JlYWRkYXRhX3JlbGVhc2U7DQotDQogCXJwY19jYWxsX3NldHVwKHRhc2ssICZtc2csIDAp Ow0KIH0NCiANCmRpZmYgLXUgLS1yZWN1cnNpdmUgLS1uZXctZmlsZSAtLXNob3ctYy1mdW5jdGlv biBsaW51eC0yLjYuMy0xOS1wcmVwYXJlX25mc3BhZ2UvZnMvbmZzL25mczR4ZHIuYyBsaW51eC0y LjYuMy0yMC1zbWFsbF9yc2l6ZS9mcy9uZnMvbmZzNHhkci5jDQotLS0gbGludXgtMi42LjMtMTkt cHJlcGFyZV9uZnNwYWdlL2ZzL25mcy9uZnM0eGRyLmMJMjAwNC0wMy0wMSAxOTo0MDoyMS4wMDAw MDAwMDAgLTA1MDANCisrKyBsaW51eC0yLjYuMy0yMC1zbWFsbF9yc2l6ZS9mcy9uZnMvbmZzNHhk ci5jCTIwMDQtMDMtMDEgMTk6NDE6MDYuMDAwMDAwMDAwIC0wNTAwDQpAQCAtODY4LDE0ICs4Njgs MzIgQEAgZW5jb2RlX3B1dHJvb3RmaChzdHJ1Y3QgeGRyX3N0cmVhbSAqeGRyKQ0KICAgICAgICAg cmV0dXJuIDA7DQogfQ0KIA0KK3N0YXRpYyB2b2lkDQorZW5jb2RlX3N0YXRlaWQoc3RydWN0IHhk cl9zdHJlYW0gKnhkciwgc3RydWN0IG5mczRfc3RhdGUgKnN0YXRlLCBmbF9vd25lcl90IGxvY2tv d25lcikNCit7DQorCWV4dGVybiBuZnM0X3N0YXRlaWQgemVyb19zdGF0ZWlkOw0KKwluZnM0X3N0 YXRlaWQgc3RhdGVpZDsNCisJdWludDMyX3QgKnA7DQorDQorCVJFU0VSVkVfU1BBQ0UoMTYpOw0K KwlpZiAoc3RhdGUgIT0gTlVMTCkgew0KKwkJbmZzNF9jb3B5X3N0YXRlaWQoJnN0YXRlaWQsIHN0 YXRlLCBsb2Nrb3duZXIpOw0KKwkJV1JJVEVNRU0oc3RhdGVpZC5kYXRhLCBzaXplb2Yoc3RhdGVp ZC5kYXRhKSk7DQorCX0gZWxzZQ0KKwkJV1JJVEVNRU0oemVyb19zdGF0ZWlkLmRhdGEsIHNpemVv Zih6ZXJvX3N0YXRlaWQuZGF0YSkpOw0KK30NCisNCiBzdGF0aWMgaW50DQogZW5jb2RlX3JlYWQo c3RydWN0IHhkcl9zdHJlYW0gKnhkciwgc3RydWN0IG5mc19yZWFkYXJncyAqYXJncykNCiB7DQog CXVpbnQzMl90ICpwOw0KIA0KLQlSRVNFUlZFX1NQQUNFKDMyKTsNCisJUkVTRVJWRV9TUEFDRSg0 KTsNCiAJV1JJVEUzMihPUF9SRUFEKTsNCi0JV1JJVEVNRU0oYXJncy0+c3RhdGVpZC5kYXRhLCBz aXplb2YoYXJncy0+c3RhdGVpZC5kYXRhKSk7DQorDQorCWVuY29kZV9zdGF0ZWlkKHhkciwgYXJn cy0+c3RhdGUsIGFyZ3MtPmxvY2tvd25lcik7DQorDQorCVJFU0VSVkVfU1BBQ0UoMTIpOw0KIAlX UklURTY0KGFyZ3MtPm9mZnNldCk7DQogCVdSSVRFMzIoYXJncy0+Y291bnQpOw0KIA0KZGlmZiAt dSAtLXJlY3Vyc2l2ZSAtLW5ldy1maWxlIC0tc2hvdy1jLWZ1bmN0aW9uIGxpbnV4LTIuNi4zLTE5 LXByZXBhcmVfbmZzcGFnZS9mcy9uZnMvcHJvYy5jIGxpbnV4LTIuNi4zLTIwLXNtYWxsX3JzaXpl L2ZzL25mcy9wcm9jLmMNCi0tLSBsaW51eC0yLjYuMy0xOS1wcmVwYXJlX25mc3BhZ2UvZnMvbmZz L3Byb2MuYwkyMDA0LTAzLTAxIDE5OjQwOjQ0LjAwMDAwMDAwMCAtMDUwMA0KKysrIGxpbnV4LTIu Ni4zLTIwLXNtYWxsX3JzaXplL2ZzL25mcy9wcm9jLmMJMjAwNC0wMy0wMSAxOTo0MTowNi4wMDAw MDAwMDAgLTA1MDANCkBAIC01NTksMTEgKzU1OSwxMCBAQCBuZnNfcmVhZF9kb25lKHN0cnVjdCBy cGNfdGFzayAqdGFzaykNCiB9DQogDQogc3RhdGljIHZvaWQNCi1uZnNfcHJvY19yZWFkX3NldHVw KHN0cnVjdCBuZnNfcmVhZF9kYXRhICpkYXRhLCB1bnNpZ25lZCBpbnQgY291bnQpDQorbmZzX3By b2NfcmVhZF9zZXR1cChzdHJ1Y3QgbmZzX3JlYWRfZGF0YSAqZGF0YSkNCiB7DQogCXN0cnVjdCBy cGNfdGFzawkJKnRhc2sgPSAmZGF0YS0+dGFzazsNCiAJc3RydWN0IGlub2RlCQkqaW5vZGUgPSBk YXRhLT5pbm9kZTsNCi0Jc3RydWN0IG5mc19wYWdlCQkqcmVxOw0KIAlpbnQJCQlmbGFnczsNCiAJ c3RydWN0IHJwY19tZXNzYWdlCW1zZyA9IHsNCiAJCS5ycGNfcHJvYwk9ICZuZnNfcHJvY2VkdXJl c1tORlNQUk9DX1JFQURdLA0KQEAgLTU3MSwyNyArNTcwLDEzIEBAIG5mc19wcm9jX3JlYWRfc2V0 dXAoc3RydWN0IG5mc19yZWFkX2RhdGENCiAJCS5ycGNfcmVzcAk9ICZkYXRhLT5yZXMsDQogCQku cnBjX2NyZWQJPSBkYXRhLT5jcmVkLA0KIAl9Ow0KLQkNCi0JcmVxID0gbmZzX2xpc3RfZW50cnko ZGF0YS0+cGFnZXMubmV4dCk7DQotCWRhdGEtPmFyZ3MuZmggICAgID0gTkZTX0ZIKGlub2RlKTsN Ci0JZGF0YS0+YXJncy5vZmZzZXQgPSByZXFfb2Zmc2V0KHJlcSk7DQotCWRhdGEtPmFyZ3MucGdi YXNlID0gcmVxLT53Yl9wZ2Jhc2U7DQotCWRhdGEtPmFyZ3MucGFnZXMgID0gZGF0YS0+cGFnZXZl YzsNCi0JZGF0YS0+YXJncy5jb3VudCAgPSBjb3VudDsNCi0JZGF0YS0+cmVzLmZhdHRyICAgPSAm ZGF0YS0+ZmF0dHI7DQotCWRhdGEtPnJlcy5jb3VudCAgID0gY291bnQ7DQotCWRhdGEtPnJlcy5l b2YgICAgID0gMDsNCi0JDQorDQogCS8qIE4uQi4gRG8gd2UgbmVlZCB0byB0ZXN0PyBOZXZlciBj YWxsZWQgZm9yIHN3YXBmaWxlIGlub2RlICovDQogCWZsYWdzID0gUlBDX1RBU0tfQVNZTkMgfCAo SVNfU1dBUEZJTEUoaW5vZGUpPyBORlNfUlBDX1NXQVBGTEFHUyA6IDApOw0KIA0KIAkvKiBGaW5h bGl6ZSB0aGUgdGFzay4gKi8NCiAJcnBjX2luaXRfdGFzayh0YXNrLCBORlNfQ0xJRU5UKGlub2Rl KSwgbmZzX3JlYWRfZG9uZSwgZmxhZ3MpOw0KLQl0YXNrLT50a19jYWxsZGF0YSA9IGRhdGE7DQot CS8qIFJlbGVhc2UgcmVxdWVzdHMgKi8NCi0JdGFzay0+dGtfcmVsZWFzZSA9IG5mc19yZWFkZGF0 YV9yZWxlYXNlOw0KLQ0KLQlycGNfY2FsbF9zZXR1cCgmZGF0YS0+dGFzaywgJm1zZywgMCk7DQor CXJwY19jYWxsX3NldHVwKHRhc2ssICZtc2csIDApOw0KIH0NCiANCiBzdGF0aWMgdm9pZA0KZGlm ZiAtdSAtLXJlY3Vyc2l2ZSAtLW5ldy1maWxlIC0tc2hvdy1jLWZ1bmN0aW9uIGxpbnV4LTIuNi4z LTE5LXByZXBhcmVfbmZzcGFnZS9mcy9uZnMvcmVhZC5jIGxpbnV4LTIuNi4zLTIwLXNtYWxsX3Jz aXplL2ZzL25mcy9yZWFkLmMNCi0tLSBsaW51eC0yLjYuMy0xOS1wcmVwYXJlX25mc3BhZ2UvZnMv bmZzL3JlYWQuYwkyMDA0LTAzLTAxIDE5OjQwOjQ0LjAwMDAwMDAwMCAtMDUwMA0KKysrIGxpbnV4 LTIuNi4zLTIwLXNtYWxsX3JzaXplL2ZzL25mcy9yZWFkLmMJMjAwNC0wMy0wMyAyMDo0MTowMS4w MDAwMDAwMDAgLTA1MDANCkBAIC0zNSw2ICszNSw4IEBADQogI2RlZmluZSBORlNEQkdfRkFDSUxJ VFkJCU5GU0RCR19QQUdFQ0FDSEUNCiANCiBzdGF0aWMgaW50IG5mc19wYWdlaW5fb25lKHN0cnVj dCBsaXN0X2hlYWQgKiwgc3RydWN0IGlub2RlICopOw0KK3N0YXRpYyB2b2lkIG5mc19yZWFkcGFn ZV9yZXN1bHRfcGFydGlhbChzdHJ1Y3QgbmZzX3JlYWRfZGF0YSAqLCBpbnQpOw0KK3N0YXRpYyB2 b2lkIG5mc19yZWFkcGFnZV9yZXN1bHRfZnVsbChzdHJ1Y3QgbmZzX3JlYWRfZGF0YSAqLCBpbnQp Ow0KIA0KIHN0YXRpYyBrbWVtX2NhY2hlX3QgKm5mc19yZGF0YV9jYWNoZXA7DQogc3RhdGljIG1l bXBvb2xfdCAqbmZzX3JkYXRhX21lbXBvb2w7DQpAQCAtNTcsMTIgKzU5LDM3IEBAIHN0YXRpYyBf X2lubGluZV9fIHZvaWQgbmZzX3JlYWRkYXRhX2ZyZWUNCiAJbWVtcG9vbF9mcmVlKHAsIG5mc19y ZGF0YV9tZW1wb29sKTsNCiB9DQogDQotdm9pZCBuZnNfcmVhZGRhdGFfcmVsZWFzZShzdHJ1Y3Qg cnBjX3Rhc2sgKnRhc2spDQorc3RhdGljIHZvaWQgbmZzX3JlYWRkYXRhX3JlbGVhc2Uoc3RydWN0 IHJwY190YXNrICp0YXNrKQ0KIHsNCiAgICAgICAgIHN0cnVjdCBuZnNfcmVhZF9kYXRhICAgKmRh dGEgPSAoc3RydWN0IG5mc19yZWFkX2RhdGEgKil0YXNrLT50a19jYWxsZGF0YTsNCiAgICAgICAg IG5mc19yZWFkZGF0YV9mcmVlKGRhdGEpOw0KIH0NCiANCitzdGF0aWMNCit1bnNpZ25lZCBpbnQg bmZzX3BhZ2VfbGVuZ3RoKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBwYWdlICpwYWdlKQ0K K3sNCisJbG9mZl90IGlfc2l6ZSA9IGlfc2l6ZV9yZWFkKGlub2RlKTsNCisJdW5zaWduZWQgbG9u ZyBpZHg7DQorDQorCWlmIChpX3NpemUgPD0gMCkNCisJCXJldHVybiAwOw0KKwlpZHggPSAoaV9z aXplIC0gMSkgPj4gUEFHRV9DQUNIRV9TSElGVDsNCisJaWYgKHBhZ2UtPmluZGV4ID4gaWR4KQ0K KwkJcmV0dXJuIDA7DQorCWlmIChwYWdlLT5pbmRleCAhPSBpZHgpDQorCQlyZXR1cm4gUEFHRV9D QUNIRV9TSVpFOw0KKwlyZXR1cm4gMSArICgoaV9zaXplIC0gMSkgJiAoUEFHRV9DQUNIRV9TSVpF IC0gMSkpOw0KK30NCisNCitzdGF0aWMNCitpbnQgbmZzX3JldHVybl9lbXB0eV9wYWdlKHN0cnVj dCBwYWdlICpwYWdlKQ0KK3sNCisJbWVtY2xlYXJfaGlnaHBhZ2VfZmx1c2gocGFnZSwgMCwgUEFH RV9DQUNIRV9TSVpFKTsNCisJU2V0UGFnZVVwdG9kYXRlKHBhZ2UpOw0KKwl1bmxvY2tfcGFnZShw YWdlKTsNCisJcmV0dXJuIDA7DQorfQ0KKw0KIC8qDQogICogUmVhZCBhIHBhZ2Ugc3luY2hyb25v dXNseS4NCiAgKi8NCkBAIC03OCw2ICsxMDUsNyBAQCBuZnNfcmVhZHBhZ2Vfc3luYyhzdHJ1Y3Qg ZmlsZSAqZmlsZSwgc3RyDQogCQkuaW5vZGUJCT0gaW5vZGUsDQogCQkuYXJncwkJPSB7DQogCQkJ LmZoCQk9IE5GU19GSChpbm9kZSksDQorCQkJLmxvY2tvd25lcgk9IGN1cnJlbnQtPmZpbGVzLA0K IAkJCS5wYWdlcwkJPSAmcGFnZSwNCiAJCQkucGdiYXNlCQk9IDBVTCwNCiAJCQkuY291bnQJCT0g cnNpemUsDQpAQCAtMTQ2LDg5ICsxNzQsMjA4IEBAIG5mc19yZWFkcGFnZV9hc3luYyhzdHJ1Y3Qg ZmlsZSAqZmlsZSwgc3QNCiB7DQogCUxJU1RfSEVBRChvbmVfcmVxdWVzdCk7DQogCXN0cnVjdCBu ZnNfcGFnZQkqbmV3Ow0KKwl1bnNpZ25lZCBpbnQgbGVuOw0KIA0KLQluZXcgPSBuZnNfY3JlYXRl X3JlcXVlc3QoZmlsZSwgaW5vZGUsIHBhZ2UsIDAsIFBBR0VfQ0FDSEVfU0laRSk7DQorCWxlbiA9 IG5mc19wYWdlX2xlbmd0aChpbm9kZSwgcGFnZSk7DQorCWlmIChsZW4gPT0gMCkNCisJCXJldHVy biBuZnNfcmV0dXJuX2VtcHR5X3BhZ2UocGFnZSk7DQorCW5ldyA9IG5mc19jcmVhdGVfcmVxdWVz dChmaWxlLCBpbm9kZSwgcGFnZSwgMCwgbGVuKTsNCiAJaWYgKElTX0VSUihuZXcpKSB7DQogCQl1 bmxvY2tfcGFnZShwYWdlKTsNCiAJCXJldHVybiBQVFJfRVJSKG5ldyk7DQogCX0NCisJaWYgKGxl biA8IFBBR0VfQ0FDSEVfU0laRSkNCisJCW1lbWNsZWFyX2hpZ2hwYWdlX2ZsdXNoKHBhZ2UsIGxl biwgUEFHRV9DQUNIRV9TSVpFIC0gbGVuKTsNCisNCiAJbmZzX2xvY2tfcmVxdWVzdChuZXcpOw0K IAluZnNfbGlzdF9hZGRfcmVxdWVzdChuZXcsICZvbmVfcmVxdWVzdCk7DQogCW5mc19wYWdlaW5f b25lKCZvbmVfcmVxdWVzdCwgaW5vZGUpOw0KIAlyZXR1cm4gMDsNCiB9DQogDQorc3RhdGljIHZv aWQgbmZzX3JlYWRwYWdlX3JlbGVhc2Uoc3RydWN0IG5mc19wYWdlICpyZXEpDQorew0KKwl1bmxv Y2tfcGFnZShyZXEtPndiX3BhZ2UpOw0KKw0KKwluZnNfY2xlYXJfcmVxdWVzdChyZXEpOw0KKwlu ZnNfcmVsZWFzZV9yZXF1ZXN0KHJlcSk7DQorCW5mc191bmxvY2tfcmVxdWVzdChyZXEpOw0KKw0K KwlkcHJpbnRrKCJORlM6IHJlYWQgZG9uZSAoJXMvJUxkICVkQCVMZClcbiIsDQorCQkJcmVxLT53 Yl9pbm9kZS0+aV9zYi0+c19pZCwNCisJCQkobG9uZyBsb25nKU5GU19GSUxFSUQocmVxLT53Yl9p bm9kZSksDQorCQkJcmVxLT53Yl9ieXRlcywNCisJCQkobG9uZyBsb25nKXJlcV9vZmZzZXQocmVx KSk7DQorfQ0KKw0KIC8qDQogICogU2V0IHVwIHRoZSBORlMgcmVhZCByZXF1ZXN0IHN0cnVjdA0K ICAqLw0KLXN0YXRpYyB2b2lkDQotbmZzX3JlYWRfcnBjc2V0dXAoc3RydWN0IGxpc3RfaGVhZCAq aGVhZCwgc3RydWN0IG5mc19yZWFkX2RhdGEgKmRhdGEpDQorc3RhdGljIHZvaWQgbmZzX3JlYWRf cnBjc2V0dXAoc3RydWN0IG5mc19wYWdlICpyZXEsIHN0cnVjdCBuZnNfcmVhZF9kYXRhICpkYXRh LA0KKwkJdW5zaWduZWQgaW50IGNvdW50LCB1bnNpZ25lZCBpbnQgb2Zmc2V0KQ0KIHsNCiAJc3Ry dWN0IGlub2RlCQkqaW5vZGU7DQotCXN0cnVjdCBuZnNfcGFnZQkJKnJlcTsNCi0Jc3RydWN0IHBh Z2UJCSoqcGFnZXM7DQotCXVuc2lnbmVkIGludAkJY291bnQ7DQogDQotCXBhZ2VzID0gZGF0YS0+ cGFnZXZlYzsNCi0JY291bnQgPSAwOw0KLQl3aGlsZSAoIWxpc3RfZW1wdHkoaGVhZCkpIHsNCi0J CXJlcSA9IG5mc19saXN0X2VudHJ5KGhlYWQtPm5leHQpOw0KLQkJbmZzX2xpc3RfcmVtb3ZlX3Jl cXVlc3QocmVxKTsNCi0JCW5mc19saXN0X2FkZF9yZXF1ZXN0KHJlcSwgJmRhdGEtPnBhZ2VzKTsN Ci0JCSpwYWdlcysrID0gcmVxLT53Yl9wYWdlOw0KLQkJY291bnQgKz0gcmVxLT53Yl9ieXRlczsN Ci0JfQ0KLQlyZXEgPSBuZnNfbGlzdF9lbnRyeShkYXRhLT5wYWdlcy5uZXh0KTsNCisJZGF0YS0+ cmVxCSAgPSByZXE7DQogCWRhdGEtPmlub2RlCSAgPSBpbm9kZSA9IHJlcS0+d2JfaW5vZGU7DQog CWRhdGEtPmNyZWQJICA9IHJlcS0+d2JfY3JlZDsNCiANCi0JTkZTX1BST1RPKGlub2RlKS0+cmVh ZF9zZXR1cChkYXRhLCBjb3VudCk7DQorCWRhdGEtPmFyZ3MuZmggICAgID0gTkZTX0ZIKGlub2Rl KTsNCisJZGF0YS0+YXJncy5vZmZzZXQgPSByZXFfb2Zmc2V0KHJlcSkgKyBvZmZzZXQ7DQorCWRh dGEtPmFyZ3MucGdiYXNlID0gcmVxLT53Yl9wZ2Jhc2UgKyBvZmZzZXQ7DQorCWRhdGEtPmFyZ3Mu cGFnZXMgID0gZGF0YS0+cGFnZXZlYzsNCisJZGF0YS0+YXJncy5jb3VudCAgPSBjb3VudDsNCisJ ZGF0YS0+YXJncy5sb2Nrb3duZXIgPSByZXEtPndiX2xvY2tvd25lcjsNCisJZGF0YS0+YXJncy5z dGF0ZSAgPSByZXEtPndiX3N0YXRlOw0KKw0KKwlkYXRhLT5yZXMuZmF0dHIgICA9ICZkYXRhLT5m YXR0cjsNCisJZGF0YS0+cmVzLmNvdW50ICAgPSBjb3VudDsNCisJZGF0YS0+cmVzLmVvZiAgICAg PSAwOw0KKw0KKwlORlNfUFJPVE8oaW5vZGUpLT5yZWFkX3NldHVwKGRhdGEpOw0KKw0KKwlkYXRh LT50YXNrLnRrX2NhbGxkYXRhID0gZGF0YTsNCisJLyogUmVsZWFzZSByZXF1ZXN0cyAqLw0KKwlk YXRhLT50YXNrLnRrX3JlbGVhc2UgPSBuZnNfcmVhZGRhdGFfcmVsZWFzZTsNCiANCi0JZHByaW50 aygiTkZTOiAlNGQgaW5pdGlhdGVkIHJlYWQgY2FsbCAocmVxICVzLyVMZCwgJXUgYnl0ZXMgQCBv ZmZzZXQgJUx1LlxuIiwNCisJZHByaW50aygiTkZTOiAlNGQgaW5pdGlhdGVkIHJlYWQgY2FsbCAo cmVxICVzLyVMZCwgJXUgYnl0ZXMgQCBvZmZzZXQgJUx1KVxuIiwNCiAJCQlkYXRhLT50YXNrLnRr X3BpZCwNCiAJCQlpbm9kZS0+aV9zYi0+c19pZCwNCiAJCQkobG9uZyBsb25nKU5GU19GSUxFSUQo aW5vZGUpLA0KIAkJCWNvdW50LA0KLQkJCSh1bnNpZ25lZCBsb25nIGxvbmcpcmVxX29mZnNldChy ZXEpKTsNCisJCQlkYXRhLT5hcmdzLm9mZnNldCk7DQogfQ0KIA0KIHN0YXRpYyB2b2lkDQogbmZz X2FzeW5jX3JlYWRfZXJyb3Ioc3RydWN0IGxpc3RfaGVhZCAqaGVhZCkNCiB7DQogCXN0cnVjdCBu ZnNfcGFnZQkqcmVxOw0KLQlzdHJ1Y3QgcGFnZQkqcGFnZTsNCiANCiAJd2hpbGUgKCFsaXN0X2Vt cHR5KGhlYWQpKSB7DQogCQlyZXEgPSBuZnNfbGlzdF9lbnRyeShoZWFkLT5uZXh0KTsNCi0JCXBh Z2UgPSByZXEtPndiX3BhZ2U7DQogCQluZnNfbGlzdF9yZW1vdmVfcmVxdWVzdChyZXEpOw0KLQkJ U2V0UGFnZUVycm9yKHBhZ2UpOw0KLQkJdW5sb2NrX3BhZ2UocGFnZSk7DQotCQluZnNfY2xlYXJf cmVxdWVzdChyZXEpOw0KLQkJbmZzX3JlbGVhc2VfcmVxdWVzdChyZXEpOw0KLQkJbmZzX3VubG9j a19yZXF1ZXN0KHJlcSk7DQorCQlTZXRQYWdlRXJyb3IocmVxLT53Yl9wYWdlKTsNCisJCW5mc19y ZWFkcGFnZV9yZWxlYXNlKHJlcSk7DQogCX0NCiB9DQogDQotc3RhdGljIGludA0KLW5mc19wYWdl aW5fb25lKHN0cnVjdCBsaXN0X2hlYWQgKmhlYWQsIHN0cnVjdCBpbm9kZSAqaW5vZGUpDQorLyoN CisgKiBTdGFydCBhbiBhc3luYyByZWFkIG9wZXJhdGlvbg0KKyAqLw0KK3N0YXRpYyB2b2lkIG5m c19leGVjdXRlX3JlYWQoc3RydWN0IG5mc19yZWFkX2RhdGEgKmRhdGEpDQorew0KKwlzdHJ1Y3Qg cnBjX2NsbnQgKmNsbnQgPSBORlNfQ0xJRU5UKGRhdGEtPmlub2RlKTsNCisJc2lnc2V0X3Qgb2xk c2V0Ow0KKw0KKwlycGNfY2xudF9zaWdtYXNrKGNsbnQsICZvbGRzZXQpOw0KKwlsb2NrX2tlcm5l bCgpOw0KKwlycGNfZXhlY3V0ZSgmZGF0YS0+dGFzayk7DQorCXVubG9ja19rZXJuZWwoKTsNCisJ cnBjX2NsbnRfc2lndW5tYXNrKGNsbnQsICZvbGRzZXQpOw0KK30NCisNCisvKg0KKyAqIEdlbmVy YXRlIG11bHRpcGxlIHJlcXVlc3RzIHRvIGZpbGwgYSBzaW5nbGUgcGFnZS4NCisgKg0KKyAqIFdl IG9wdGltaXplIHRvIHJlZHVjZSB0aGUgbnVtYmVyIG9mIHJlYWQgb3BlcmF0aW9ucyBvbiB0aGUg d2lyZS4gIElmIHdlDQorICogZGV0ZWN0IHRoYXQgd2UncmUgcmVhZGluZyBhIHBhZ2UsIG9yIGFu IGFyZWEgb2YgYSBwYWdlLCB0aGF0IGlzIHBhc3QgdGhlDQorICogZW5kIG9mIGZpbGUsIHdlIGRv IG5vdCBnZW5lcmF0ZSBORlMgcmVhZCBvcGVyYXRpb25zIGJ1dCBqdXN0IGNsZWFyIHRoZQ0KKyAq IHBhcnRzIG9mIHRoZSBwYWdlIHRoYXQgd291bGQgaGF2ZSBjb21lIGJhY2sgemVybyBmcm9tIHRo ZSBzZXJ2ZXIgYW55d2F5Lg0KKyAqDQorICogV2UgcmVseSBvbiB0aGUgY2FjaGVkIHZhbHVlIG9m IGlfc2l6ZSB0byBtYWtlIHRoaXMgZGV0ZXJtaW5hdGlvbjsgYW5vdGhlcg0KKyAqIGNsaWVudCBj YW4gZmlsbCBwYWdlcyBvbiB0aGUgc2VydmVyIHBhc3Qgb3VyIGNhY2hlZCBlbmQtb2YtZmlsZSwg YnV0IHdlDQorICogd29uJ3Qgc2VlIHRoZSBuZXcgZGF0YSB1bnRpbCBvdXIgYXR0cmlidXRlIGNh Y2hlIGlzIHVwZGF0ZWQuICBUaGlzIGlzIG1vcmUNCisgKiBvciBsZXNzIGNvbnZlbnRpb25hbCBO RlMgY2xpZW50IGJlaGF2aW9yLg0KKyAqLw0KK3N0YXRpYyBpbnQgbmZzX3BhZ2Vpbl9tdWx0aShz dHJ1Y3QgbGlzdF9oZWFkICpoZWFkLCBzdHJ1Y3QgaW5vZGUgKmlub2RlKQ0KK3sNCisJc3RydWN0 IG5mc19wYWdlICpyZXEgPSBuZnNfbGlzdF9lbnRyeShoZWFkLT5uZXh0KTsNCisJc3RydWN0IHBh Z2UgKnBhZ2UgPSByZXEtPndiX3BhZ2U7DQorCXN0cnVjdCBuZnNfcmVhZF9kYXRhICpkYXRhOw0K Kwl1bnNpZ25lZCBpbnQgcnNpemUgPSBORlNfU0VSVkVSKGlub2RlKS0+cnNpemU7DQorCXVuc2ln bmVkIGludCBuYnl0ZXMsIG9mZnNldDsNCisJaW50IHJlcXVlc3RzID0gMDsNCisJTElTVF9IRUFE KGxpc3QpOw0KKw0KKwluZnNfbGlzdF9yZW1vdmVfcmVxdWVzdChyZXEpOw0KKw0KKwluYnl0ZXMg PSByZXEtPndiX2J5dGVzOw0KKwlmb3IoOzspIHsNCisJCWRhdGEgPSBuZnNfcmVhZGRhdGFfYWxs b2MoKTsNCisJCWlmICghZGF0YSkNCisJCQlnb3RvIG91dF9iYWQ7DQorCQlsaXN0X2FkZCgmZGF0 YS0+cGFnZXMsICZsaXN0KTsNCisJCXJlcXVlc3RzKys7DQorCQlpZiAobmJ5dGVzIDw9IHJzaXpl KQ0KKwkJCWJyZWFrOw0KKwkJbmJ5dGVzIC09IHJzaXplOw0KKwl9DQorCWF0b21pY19zZXQoJnJl cS0+d2JfY29tcGxldGUsIHJlcXVlc3RzKTsNCisNCisJQ2xlYXJQYWdlRXJyb3IocGFnZSk7DQor CW9mZnNldCA9IDA7DQorCW5ieXRlcyA9IHJlcS0+d2JfYnl0ZXM7DQorCWRvIHsNCisJCWRhdGEg PSBsaXN0X2VudHJ5KGxpc3QubmV4dCwgc3RydWN0IG5mc19yZWFkX2RhdGEsIHBhZ2VzKTsNCisJ CWxpc3RfZGVsX2luaXQoJmRhdGEtPnBhZ2VzKTsNCisNCisJCWRhdGEtPnBhZ2V2ZWNbMF0gPSBw YWdlOw0KKwkJZGF0YS0+Y29tcGxldGUgPSBuZnNfcmVhZHBhZ2VfcmVzdWx0X3BhcnRpYWw7DQor DQorCQlpZiAobmJ5dGVzID4gcnNpemUpIHsNCisJCQluZnNfcmVhZF9ycGNzZXR1cChyZXEsIGRh dGEsIHJzaXplLCBvZmZzZXQpOw0KKwkJCW9mZnNldCArPSByc2l6ZTsNCisJCQluYnl0ZXMgLT0g cnNpemU7DQorCQl9IGVsc2Ugew0KKwkJCW5mc19yZWFkX3JwY3NldHVwKHJlcSwgZGF0YSwgbmJ5 dGVzLCBvZmZzZXQpOw0KKwkJCW5ieXRlcyA9IDA7DQorCQl9DQorCQluZnNfZXhlY3V0ZV9yZWFk KGRhdGEpOw0KKwl9IHdoaWxlIChuYnl0ZXMgIT0gMCk7DQorDQorCXJldHVybiAwOw0KKw0KK291 dF9iYWQ6DQorCXdoaWxlICghbGlzdF9lbXB0eSgmbGlzdCkpIHsNCisJCWRhdGEgPSBsaXN0X2Vu dHJ5KGxpc3QubmV4dCwgc3RydWN0IG5mc19yZWFkX2RhdGEsIHBhZ2VzKTsNCisJCWxpc3RfZGVs KCZkYXRhLT5wYWdlcyk7DQorCQluZnNfcmVhZGRhdGFfZnJlZShkYXRhKTsNCisJfQ0KKwlTZXRQ YWdlRXJyb3IocGFnZSk7DQorCW5mc19yZWFkcGFnZV9yZWxlYXNlKHJlcSk7DQorCXJldHVybiAt RU5PTUVNOw0KK30NCisNCitzdGF0aWMgaW50IG5mc19wYWdlaW5fb25lKHN0cnVjdCBsaXN0X2hl YWQgKmhlYWQsIHN0cnVjdCBpbm9kZSAqaW5vZGUpDQogew0KLQlzdHJ1Y3QgcnBjX2NsbnQJCSpj bG50ID0gTkZTX0NMSUVOVChpbm9kZSk7DQorCXN0cnVjdCBuZnNfcGFnZQkJKnJlcTsNCisJc3Ry dWN0IHBhZ2UJCSoqcGFnZXM7DQogCXN0cnVjdCBuZnNfcmVhZF9kYXRhCSpkYXRhOw0KLQlzaWdz ZXRfdAkJb2xkc2V0Ow0KKwl1bnNpZ25lZCBpbnQJCWNvdW50Ow0KKw0KKwlpZiAoTkZTX1NFUlZF Uihpbm9kZSktPnJzaXplIDwgUEFHRV9DQUNIRV9TSVpFKQ0KKwkJcmV0dXJuIG5mc19wYWdlaW5f bXVsdGkoaGVhZCwgaW5vZGUpOw0KIA0KIAlkYXRhID0gbmZzX3JlYWRkYXRhX2FsbG9jKCk7DQog CWlmICghZGF0YSkNCiAJCWdvdG8gb3V0X2JhZDsNCiANCi0JbmZzX3JlYWRfcnBjc2V0dXAoaGVh ZCwgZGF0YSk7DQorCXBhZ2VzID0gZGF0YS0+cGFnZXZlYzsNCisJY291bnQgPSAwOw0KKwl3aGls ZSAoIWxpc3RfZW1wdHkoaGVhZCkpIHsNCisJCXJlcSA9IG5mc19saXN0X2VudHJ5KGhlYWQtPm5l eHQpOw0KKwkJbmZzX2xpc3RfcmVtb3ZlX3JlcXVlc3QocmVxKTsNCisJCW5mc19saXN0X2FkZF9y ZXF1ZXN0KHJlcSwgJmRhdGEtPnBhZ2VzKTsNCisJCUNsZWFyUGFnZUVycm9yKHJlcS0+d2JfcGFn ZSk7DQorCQkqcGFnZXMrKyA9IHJlcS0+d2JfcGFnZTsNCisJCWNvdW50ICs9IHJlcS0+d2JfYnl0 ZXM7DQorCX0NCisJcmVxID0gbmZzX2xpc3RfZW50cnkoZGF0YS0+cGFnZXMubmV4dCk7DQorDQor CWRhdGEtPmNvbXBsZXRlID0gbmZzX3JlYWRwYWdlX3Jlc3VsdF9mdWxsOw0KKwluZnNfcmVhZF9y cGNzZXR1cChyZXEsIGRhdGEsIGNvdW50LCAwKTsNCiANCi0JLyogU3RhcnQgdGhlIGFzeW5jIGNh bGwgKi8NCi0JcnBjX2NsbnRfc2lnbWFzayhjbG50LCAmb2xkc2V0KTsNCi0JbG9ja19rZXJuZWwo KTsNCi0JcnBjX2V4ZWN1dGUoJmRhdGEtPnRhc2spOw0KLQl1bmxvY2tfa2VybmVsKCk7DQotCXJw Y19jbG50X3NpZ3VubWFzayhjbG50LCAmb2xkc2V0KTsNCisJbmZzX2V4ZWN1dGVfcmVhZChkYXRh KTsNCiAJcmV0dXJuIDA7DQogb3V0X2JhZDoNCiAJbmZzX2FzeW5jX3JlYWRfZXJyb3IoaGVhZCk7 DQpAQCAtMjU4LDU1ICs0MDUsODQgQEAgbmZzX3BhZ2Vpbl9saXN0KHN0cnVjdCBsaXN0X2hlYWQg KmhlYWQsIA0KIH0NCiANCiAvKg0KKyAqIEhhbmRsZSBhIHJlYWQgcmVwbHkgdGhhdCBmaWxscyBw YXJ0IG9mIGEgcGFnZS4NCisgKi8NCitzdGF0aWMgdm9pZCBuZnNfcmVhZHBhZ2VfcmVzdWx0X3Bh cnRpYWwoc3RydWN0IG5mc19yZWFkX2RhdGEgKmRhdGEsIGludCBzdGF0dXMpDQorew0KKwlzdHJ1 Y3QgbmZzX3BhZ2UgKnJlcSA9IGRhdGEtPnJlcTsNCisJc3RydWN0IHBhZ2UgKnBhZ2UgPSByZXEt PndiX3BhZ2U7DQorIA0KKwlpZiAoc3RhdHVzID49IDApIHsNCisJCXVuc2lnbmVkIGludCByZXF1 ZXN0ID0gZGF0YS0+YXJncy5jb3VudDsNCisJCXVuc2lnbmVkIGludCByZXN1bHQgPSBkYXRhLT5y ZXMuY291bnQ7DQorDQorCQlpZiAocmVzdWx0IDwgcmVxdWVzdCkgew0KKwkJCW1lbWNsZWFyX2hp Z2hwYWdlX2ZsdXNoKHBhZ2UsDQorCQkJCQkJZGF0YS0+YXJncy5wZ2Jhc2UgKyByZXN1bHQsDQor CQkJCQkJcmVxdWVzdCAtIHJlc3VsdCk7DQorCQkJaWYgKCFkYXRhLT5yZXMuZW9mKQ0KKwkJCQlT ZXRQYWdlRXJyb3IocGFnZSk7DQorCQl9DQorCX0gZWxzZQ0KKwkJU2V0UGFnZUVycm9yKHBhZ2Up Ow0KKw0KKwlpZiAoYXRvbWljX2RlY19hbmRfdGVzdCgmcmVxLT53Yl9jb21wbGV0ZSkpIHsNCisJ CWlmICghUGFnZUVycm9yKHBhZ2UpKQ0KKwkJCVNldFBhZ2VVcHRvZGF0ZShwYWdlKTsNCisJCW5m c19yZWFkcGFnZV9yZWxlYXNlKHJlcSk7DQorCX0NCit9DQorDQorLyoNCiAgKiBUaGlzIGlzIHRo ZSBjYWxsYmFjayBmcm9tIFJQQyB0ZWxsaW5nIHVzIHdoZXRoZXIgYSByZXBseSB3YXMNCiAgKiBy ZWNlaXZlZCBvciBzb21lIGVycm9yIG9jY3VycmVkICh0aW1lb3V0IG9yIHNvY2tldCBzaHV0ZG93 bikuDQogICovDQotdm9pZA0KLW5mc19yZWFkcGFnZV9yZXN1bHQoc3RydWN0IHJwY190YXNrICp0 YXNrKQ0KK3N0YXRpYyB2b2lkIG5mc19yZWFkcGFnZV9yZXN1bHRfZnVsbChzdHJ1Y3QgbmZzX3Jl YWRfZGF0YSAqZGF0YSwgaW50IHN0YXR1cykNCiB7DQotCXN0cnVjdCBuZnNfcmVhZF9kYXRhICpk YXRhID0gKHN0cnVjdCBuZnNfcmVhZF9kYXRhICopdGFzay0+dGtfY2FsbGRhdGE7DQogCXVuc2ln bmVkIGludCBjb3VudCA9IGRhdGEtPnJlcy5jb3VudDsNCiANCi0JZHByaW50aygiTkZTOiAlNGQg bmZzX3JlYWRwYWdlX3Jlc3VsdCwgKHN0YXR1cyAlZClcbiIsDQotCQl0YXNrLT50a19waWQsIHRh c2stPnRrX3N0YXR1cyk7DQotDQotCU5GU19GTEFHUyhkYXRhLT5pbm9kZSkgfD0gTkZTX0lOT19J TlZBTElEX0FUSU1FOw0KIAl3aGlsZSAoIWxpc3RfZW1wdHkoJmRhdGEtPnBhZ2VzKSkgew0KIAkJ c3RydWN0IG5mc19wYWdlICpyZXEgPSBuZnNfbGlzdF9lbnRyeShkYXRhLT5wYWdlcy5uZXh0KTsN CiAJCXN0cnVjdCBwYWdlICpwYWdlID0gcmVxLT53Yl9wYWdlOw0KIAkJbmZzX2xpc3RfcmVtb3Zl X3JlcXVlc3QocmVxKTsNCiANCi0JCWlmICh0YXNrLT50a19zdGF0dXMgPj0gMCkgew0KKwkJaWYg KHN0YXR1cyA+PSAwKSB7DQogCQkJaWYgKGNvdW50IDwgUEFHRV9DQUNIRV9TSVpFKSB7DQotCQkJ CW1lbWNsZWFyX2hpZ2hwYWdlX2ZsdXNoKHBhZ2UsDQorCQkJCWlmIChjb3VudCA8IHJlcS0+d2Jf Ynl0ZXMpDQorCQkJCQltZW1jbGVhcl9oaWdocGFnZV9mbHVzaChwYWdlLA0KIAkJCQkJCQlyZXEt PndiX3BnYmFzZSArIGNvdW50LA0KIAkJCQkJCQlyZXEtPndiX2J5dGVzIC0gY291bnQpOw0KLQ0K KwkJCQlpZiAoIWRhdGEtPnJlcy5lb2YpDQorCQkJCQlTZXRQYWdlRXJyb3IocGFnZSk7DQogCQkJ CWNvdW50ID0gMDsNCiAJCQl9IGVsc2UNCiAJCQkJY291bnQgLT0gUEFHRV9DQUNIRV9TSVpFOw0K IAkJCVNldFBhZ2VVcHRvZGF0ZShwYWdlKTsNCiAJCX0gZWxzZQ0KIAkJCVNldFBhZ2VFcnJvcihw YWdlKTsNCi0JCXVubG9ja19wYWdlKHBhZ2UpOw0KLQ0KLQkJZHByaW50aygiTkZTOiByZWFkICgl cy8lTGQgJWRAJUxkKVxuIiwNCi0gICAgICAgICAgICAgICAgICAgICAgICByZXEtPndiX2lub2Rl LT5pX3NiLT5zX2lkLA0KLSAgICAgICAgICAgICAgICAgICAgICAgIChsb25nIGxvbmcpTkZTX0ZJ TEVJRChyZXEtPndiX2lub2RlKSwNCi0gICAgICAgICAgICAgICAgICAgICAgICByZXEtPndiX2J5 dGVzLA0KLSAgICAgICAgICAgICAgICAgICAgICAgIChsb25nIGxvbmcpcmVxX29mZnNldChyZXEp KTsNCi0JCW5mc19jbGVhcl9yZXF1ZXN0KHJlcSk7DQotCQluZnNfcmVsZWFzZV9yZXF1ZXN0KHJl cSk7DQotCQluZnNfdW5sb2NrX3JlcXVlc3QocmVxKTsNCisJCW5mc19yZWFkcGFnZV9yZWxlYXNl KHJlcSk7DQogCX0NCiB9DQogDQogLyoNCisgKiBUaGlzIGlzIHRoZSBjYWxsYmFjayBmcm9tIFJQ QyB0ZWxsaW5nIHVzIHdoZXRoZXIgYSByZXBseSB3YXMNCisgKiByZWNlaXZlZCBvciBzb21lIGVy cm9yIG9jY3VycmVkICh0aW1lb3V0IG9yIHNvY2tldCBzaHV0ZG93bikuDQorICovDQordm9pZCBu ZnNfcmVhZHBhZ2VfcmVzdWx0KHN0cnVjdCBycGNfdGFzayAqdGFzaykNCit7DQorCXN0cnVjdCBu ZnNfcmVhZF9kYXRhICpkYXRhID0gKHN0cnVjdCBuZnNfcmVhZF9kYXRhICopdGFzay0+dGtfY2Fs bGRhdGE7DQorCWludCBzdGF0dXMgPSB0YXNrLT50a19zdGF0dXM7DQorDQorCWRwcmludGsoIk5G UzogJTRkIG5mc19yZWFkcGFnZV9yZXN1bHQsIChzdGF0dXMgJWQpXG4iLA0KKwkJdGFzay0+dGtf cGlkLCBzdGF0dXMpOw0KKw0KKwlORlNfRkxBR1MoZGF0YS0+aW5vZGUpIHw9IE5GU19JTk9fSU5W QUxJRF9BVElNRTsNCisJZGF0YS0+Y29tcGxldGUoZGF0YSwgc3RhdHVzKTsNCit9DQorDQorLyoN CiAgKiBSZWFkIGEgcGFnZSBvdmVyIE5GUy4NCi0gKiBXZSByZWFkIHRoZSBwYWdlIHN5bmNocm9u b3VzbHkgaW4gdGhlIGZvbGxvd2luZyBjYXNlczoNCi0gKiAgLQlUaGUgTkZTIHJzaXplIGlzIHNt YWxsZXIgdGhhbiBQQUdFX0NBQ0hFX1NJWkUuIFdlIGNvdWxkIGtsdWRnZSBvdXIgd2F5DQotICoJ YXJvdW5kIHRoaXMgYnkgY3JlYXRpbmcgc2V2ZXJhbCBjb25zZWN1dGl2ZSByZWFkIHJlcXVlc3Rz LCBidXQNCi0gKgl0aGF0J3MgaGFyZGx5IHdvcnRoIGl0Lg0KKyAqIFdlIHJlYWQgdGhlIHBhZ2Ug c3luY2hyb25vdXNseSBpbiB0aGUgZm9sbG93aW5nIGNhc2U6DQogICogIC0JVGhlIGVycm9yIGZs YWcgaXMgc2V0IGZvciB0aGlzIHBhZ2UuIFRoaXMgaGFwcGVucyBvbmx5IHdoZW4gYQ0KICAqCXBy ZXZpb3VzIGFzeW5jIHJlYWQgb3BlcmF0aW9uIGZhaWxlZC4NCiAgKi8NCkBAIC0zMjksNyArNTA1 LDcgQEAgbmZzX3JlYWRwYWdlKHN0cnVjdCBmaWxlICpmaWxlLCBzdHJ1Y3QgcA0KIAlpZiAoZXJy b3IpDQogCQlnb3RvIG91dF9lcnJvcjsNCiANCi0JaWYgKCFQYWdlRXJyb3IocGFnZSkgJiYgTkZT X1NFUlZFUihpbm9kZSktPnJzaXplID49IFBBR0VfQ0FDSEVfU0laRSkgew0KKwlpZiAoIUlTX1NZ TkMoaW5vZGUpKSB7DQogCQllcnJvciA9IG5mc19yZWFkcGFnZV9hc3luYyhmaWxlLCBpbm9kZSwg cGFnZSk7DQogCQlnb3RvIG91dDsNCiAJfQ0KQEAgLTM1MSwyNiArNTI3LDI1IEBAIHN0cnVjdCBu ZnNfcmVhZGRlc2Mgew0KIH07DQogDQogc3RhdGljIGludA0KLXJlYWRwYWdlX3N5bmNfZmlsbGVy KHZvaWQgKmRhdGEsIHN0cnVjdCBwYWdlICpwYWdlKQ0KLXsNCi0Jc3RydWN0IG5mc19yZWFkZGVz YyAqZGVzYyA9IChzdHJ1Y3QgbmZzX3JlYWRkZXNjICopZGF0YTsNCi0JcmV0dXJuIG5mc19yZWFk cGFnZV9zeW5jKGRlc2MtPmZpbHAsIHBhZ2UtPm1hcHBpbmctPmhvc3QsIHBhZ2UpOw0KLX0NCi0N Ci1zdGF0aWMgaW50DQogcmVhZHBhZ2VfYXN5bmNfZmlsbGVyKHZvaWQgKmRhdGEsIHN0cnVjdCBw YWdlICpwYWdlKQ0KIHsNCiAJc3RydWN0IG5mc19yZWFkZGVzYyAqZGVzYyA9IChzdHJ1Y3QgbmZz X3JlYWRkZXNjICopZGF0YTsNCiAJc3RydWN0IGlub2RlICppbm9kZSA9IHBhZ2UtPm1hcHBpbmct Pmhvc3Q7DQogCXN0cnVjdCBuZnNfcGFnZSAqbmV3Ow0KKwl1bnNpZ25lZCBpbnQgbGVuOw0KIA0K IAluZnNfd2JfcGFnZShpbm9kZSwgcGFnZSk7DQotCW5ldyA9IG5mc19jcmVhdGVfcmVxdWVzdChk ZXNjLT5maWxwLCBpbm9kZSwgcGFnZSwgMCwgUEFHRV9DQUNIRV9TSVpFKTsNCisJbGVuID0gbmZz X3BhZ2VfbGVuZ3RoKGlub2RlLCBwYWdlKTsNCisJaWYgKGxlbiA9PSAwKQ0KKwkJcmV0dXJuIG5m c19yZXR1cm5fZW1wdHlfcGFnZShwYWdlKTsNCisJbmV3ID0gbmZzX2NyZWF0ZV9yZXF1ZXN0KGRl c2MtPmZpbHAsIGlub2RlLCBwYWdlLCAwLCBsZW4pOw0KIAlpZiAoSVNfRVJSKG5ldykpIHsNCiAJ CQlTZXRQYWdlRXJyb3IocGFnZSk7DQogCQkJdW5sb2NrX3BhZ2UocGFnZSk7DQogCQkJcmV0dXJu IFBUUl9FUlIobmV3KTsNCiAJfQ0KKwlpZiAobGVuIDwgUEFHRV9DQUNIRV9TSVpFKQ0KKwkJbWVt Y2xlYXJfaGlnaHBhZ2VfZmx1c2gocGFnZSwgbGVuLCBQQUdFX0NBQ0hFX1NJWkUgLSBsZW4pOw0K IAluZnNfbG9ja19yZXF1ZXN0KG5ldyk7DQogCW5mc19saXN0X2FkZF9yZXF1ZXN0KG5ldywgZGVz Yy0+aGVhZCk7DQogCXJldHVybiAwOw0KQEAgLTM4NSwxNCArNTYwLDE2IEBAIG5mc19yZWFkcGFn ZXMoc3RydWN0IGZpbGUgKmZpbHAsIHN0cnVjdCANCiAJCS5maWxwCQk9IGZpbHAsDQogCQkuaGVh ZAkJPSAmaGVhZCwNCiAJfTsNCi0Jc3RydWN0IG5mc19zZXJ2ZXIgKnNlcnZlciA9IE5GU19TRVJW RVIobWFwcGluZy0+aG9zdCk7DQotCWludCBpc19zeW5jID0gc2VydmVyLT5yc2l6ZSA8IFBBR0Vf Q0FDSEVfU0laRTsNCisJc3RydWN0IGlub2RlICppbm9kZSA9IG1hcHBpbmctPmhvc3Q7DQorCXN0 cnVjdCBuZnNfc2VydmVyICpzZXJ2ZXIgPSBORlNfU0VSVkVSKGlub2RlKTsNCiAJaW50IHJldDsN CiANCi0JcmV0ID0gcmVhZF9jYWNoZV9wYWdlcyhtYXBwaW5nLCBwYWdlcywNCi0JCQkgICAgICAg aXNfc3luYyA/IHJlYWRwYWdlX3N5bmNfZmlsbGVyIDoNCi0JCQkJCSByZWFkcGFnZV9hc3luY19m aWxsZXIsDQotCQkJICAgICAgICZkZXNjKTsNCisJZHByaW50aygiTkZTOiBuZnNfcmVhZHBhZ2Vz ICglcy8lTGQgJWQpXG4iLA0KKwkJCWlub2RlLT5pX3NiLT5zX2lkLA0KKwkJCShsb25nIGxvbmcp TkZTX0ZJTEVJRChpbm9kZSksDQorCQkJbnJfcGFnZXMpOw0KKw0KKwlyZXQgPSByZWFkX2NhY2hl X3BhZ2VzKG1hcHBpbmcsIHBhZ2VzLCByZWFkcGFnZV9hc3luY19maWxsZXIsICZkZXNjKTsNCiAJ aWYgKCFsaXN0X2VtcHR5KCZoZWFkKSkgew0KIAkJaW50IGVyciA9IG5mc19wYWdlaW5fbGlzdCgm aGVhZCwgc2VydmVyLT5ycGFnZXMpOw0KIAkJaWYgKCFyZXQpDQpkaWZmIC11IC0tcmVjdXJzaXZl IC0tbmV3LWZpbGUgLS1zaG93LWMtZnVuY3Rpb24gbGludXgtMi42LjMtMTktcHJlcGFyZV9uZnNw YWdlL2luY2x1ZGUvbGludXgvbmZzX2ZzLmggbGludXgtMi42LjMtMjAtc21hbGxfcnNpemUvaW5j bHVkZS9saW51eC9uZnNfZnMuaA0KLS0tIGxpbnV4LTIuNi4zLTE5LXByZXBhcmVfbmZzcGFnZS9p bmNsdWRlL2xpbnV4L25mc19mcy5oCTIwMDQtMDMtMDEgMTk6Mzk6MzMuMDAwMDAwMDAwIC0wNTAw DQorKysgbGludXgtMi42LjMtMjAtc21hbGxfcnNpemUvaW5jbHVkZS9saW51eC9uZnNfZnMuaAky MDA0LTAzLTAxIDE5OjQxOjA2LjAwMDAwMDAwMCAtMDUwMA0KQEAgLTM5NCw3ICszOTQsNiBAQCBl eHRlcm4gaW50ICBuZnNfcmVhZHBhZ2VzKHN0cnVjdCBmaWxlICosDQogCQlzdHJ1Y3QgbGlzdF9o ZWFkICosIHVuc2lnbmVkKTsNCiBleHRlcm4gaW50ICBuZnNfcGFnZWluX2xpc3Qoc3RydWN0IGxp c3RfaGVhZCAqLCBpbnQpOw0KIGV4dGVybiB2b2lkIG5mc19yZWFkcGFnZV9yZXN1bHQoc3RydWN0 IHJwY190YXNrICopOw0KLWV4dGVybiB2b2lkIG5mc19yZWFkZGF0YV9yZWxlYXNlKHN0cnVjdCBy cGNfdGFzayAqKTsNCiANCiAvKg0KICAqIGxpbnV4L2ZzL21vdW50X2NsbnQuYw0KZGlmZiAtdSAt LXJlY3Vyc2l2ZSAtLW5ldy1maWxlIC0tc2hvdy1jLWZ1bmN0aW9uIGxpbnV4LTIuNi4zLTE5LXBy ZXBhcmVfbmZzcGFnZS9pbmNsdWRlL2xpbnV4L25mc194ZHIuaCBsaW51eC0yLjYuMy0yMC1zbWFs bF9yc2l6ZS9pbmNsdWRlL2xpbnV4L25mc194ZHIuaA0KLS0tIGxpbnV4LTIuNi4zLTE5LXByZXBh cmVfbmZzcGFnZS9pbmNsdWRlL2xpbnV4L25mc194ZHIuaAkyMDA0LTAzLTAxIDE5OjQwOjU1LjAw MDAwMDAwMCAtMDUwMA0KKysrIGxpbnV4LTIuNi4zLTIwLXNtYWxsX3JzaXplL2luY2x1ZGUvbGlu dXgvbmZzX3hkci5oCTIwMDQtMDMtMDEgMTk6NDE6MDYuMDAwMDAwMDAwIC0wNTAwDQpAQCAtMjI5 LDcgKzIyOSw4IEBAIHN0cnVjdCBuZnNfbG9ja3JlcyB7DQogDQogc3RydWN0IG5mc19yZWFkYXJn cyB7DQogCXN0cnVjdCBuZnNfZmggKgkJZmg7DQotCW5mczRfc3RhdGVpZAkJc3RhdGVpZDsNCisJ Zmxfb3duZXJfdAkJbG9ja293bmVyOw0KKwlzdHJ1Y3QgbmZzNF9zdGF0ZSAqCXN0YXRlOw0KIAlf X3U2NAkJCW9mZnNldDsNCiAJX191MzIJCQljb3VudDsNCiAJdW5zaWduZWQgaW50CQlwZ2Jhc2U7 DQpAQCAtNjYzLDcgKzY2NCw2IEBAIHN0cnVjdCBuZnNfcmVhZF9kYXRhIHsNCiAJc3RydWN0IHJw Y190YXNrCQl0YXNrOw0KIAlzdHJ1Y3QgaW5vZGUJCSppbm9kZTsNCiAJc3RydWN0IHJwY19jcmVk CQkqY3JlZDsNCi0JZmxfb3duZXJfdAkJbG9ja293bmVyOw0KIAlzdHJ1Y3QgbmZzX2ZhdHRyCWZh dHRyOwkvKiBmYXR0ciBzdG9yYWdlICovDQogCXN0cnVjdCBsaXN0X2hlYWQJcGFnZXM7CS8qIENv YWxlc2NlZCByZWFkIHJlcXVlc3RzICovDQogCXN0cnVjdCBuZnNfcGFnZQkJKnJlcTsJLyogbXVs dGkgb3BzIHBlciBuZnNfcGFnZSAqLw0KQEAgLTc0MSw3ICs3NDEsNyBAQCBzdHJ1Y3QgbmZzX3Jw Y19vcHMgew0KIAlpbnQJKCpwYXRoY29uZikgKHN0cnVjdCBuZnNfc2VydmVyICosIHN0cnVjdCBu ZnNfZmggKiwNCiAJCQkgICAgIHN0cnVjdCBuZnNfcGF0aGNvbmYgKik7DQogCXUzMiAqCSgqZGVj b2RlX2RpcmVudCkodTMyICosIHN0cnVjdCBuZnNfZW50cnkgKiwgaW50IHBsdXMpOw0KLQl2b2lk CSgqcmVhZF9zZXR1cCkgICAoc3RydWN0IG5mc19yZWFkX2RhdGEgKiwgdW5zaWduZWQgaW50IGNv dW50KTsNCisJdm9pZAkoKnJlYWRfc2V0dXApICAgKHN0cnVjdCBuZnNfcmVhZF9kYXRhICopOw0K IAl2b2lkCSgqd3JpdGVfc2V0dXApICAoc3RydWN0IG5mc193cml0ZV9kYXRhICosIHVuc2lnbmVk IGludCBjb3VudCwgaW50IGhvdyk7DQogCXZvaWQJKCpjb21taXRfc2V0dXApIChzdHJ1Y3QgbmZz X3dyaXRlX2RhdGEgKiwgdTY0IHN0YXJ0LCB1MzIgbGVuLCBpbnQgaG93KTsNCiAJaW50CSgqZmls ZV9vcGVuKSAgIChzdHJ1Y3QgaW5vZGUgKiwgc3RydWN0IGZpbGUgKik7DQo= --=-O2aAqp6DrzPwP3KoW56V-- --- 25-akpm/fs/nfs/direct.c | 1 25-akpm/fs/nfs/nfs3proc.c | 21 -- 25-akpm/fs/nfs/nfs4proc.c | 41 ---- 25-akpm/fs/nfs/nfs4xdr.c | 22 ++ 25-akpm/fs/nfs/proc.c | 21 -- 25-akpm/fs/nfs/read.c | 331 ++++++++++++++++++++++++++++++---------- 25-akpm/include/linux/nfs_fs.h | 1 25-akpm/include/linux/nfs_xdr.h | 6 8 files changed, 288 insertions(+), 156 deletions(-) diff -puN fs/nfs/direct.c~nfs-02-small_rsize fs/nfs/direct.c --- 25/fs/nfs/direct.c~nfs-02-small_rsize 2004-03-14 15:12:31.174991152 -0800 +++ 25-akpm/fs/nfs/direct.c 2004-03-14 15:12:31.186989328 -0800 @@ -128,6 +128,7 @@ nfs_direct_read_seg(struct inode *inode, .inode = inode, .args = { .fh = NFS_FH(inode), + .lockowner = current->files, }, .res = { .fattr = &rdata.fattr, diff -puN fs/nfs/nfs3proc.c~nfs-02-small_rsize fs/nfs/nfs3proc.c --- 25/fs/nfs/nfs3proc.c~nfs-02-small_rsize 2004-03-14 15:12:31.175991000 -0800 +++ 25-akpm/fs/nfs/nfs3proc.c 2004-03-14 15:12:31.187989176 -0800 @@ -729,11 +729,10 @@ nfs3_read_done(struct rpc_task *task) } static void -nfs3_proc_read_setup(struct nfs_read_data *data, unsigned int count) +nfs3_proc_read_setup(struct nfs_read_data *data) { struct rpc_task *task = &data->task; struct inode *inode = data->inode; - struct nfs_page *req; int flags; struct rpc_message msg = { .rpc_proc = &nfs3_procedures[NFS3PROC_READ], @@ -741,27 +740,13 @@ nfs3_proc_read_setup(struct nfs_read_dat .rpc_resp = &data->res, .rpc_cred = data->cred, }; - - req = nfs_list_entry(data->pages.next); - data->args.fh = NFS_FH(inode); - data->args.offset = req_offset(req); - data->args.pgbase = req->wb_pgbase; - data->args.pages = data->pagevec; - data->args.count = count; - data->res.fattr = &data->fattr; - data->res.count = count; - data->res.eof = 0; - + /* N.B. Do we need to test? Never called for swapfile inode */ flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0); /* Finalize the task. */ rpc_init_task(task, NFS_CLIENT(inode), nfs3_read_done, flags); - task->tk_calldata = data; - /* Release requests */ - task->tk_release = nfs_readdata_release; - - rpc_call_setup(&data->task, &msg, 0); + rpc_call_setup(task, &msg, 0); } static void diff -puN fs/nfs/nfs4proc.c~nfs-02-small_rsize fs/nfs/nfs4proc.c --- 25/fs/nfs/nfs4proc.c~nfs-02-small_rsize 2004-03-14 15:12:31.177990696 -0800 +++ 25-akpm/fs/nfs/nfs4proc.c 2004-03-14 15:12:31.190988720 -0800 @@ -1096,10 +1096,10 @@ nfs4_proc_read(struct nfs_read_data *rda if (filp) { struct nfs4_state *state; state = (struct nfs4_state *)filp->private_data; - nfs4_copy_stateid(&rdata->args.stateid, state, rdata->lockowner); + rdata->args.state = state; msg.rpc_cred = state->owner->so_cred; } else { - memcpy(&rdata->args.stateid, &zero_stateid, sizeof(rdata->args.stateid)); + rdata->args.state = NULL; msg.rpc_cred = NFS_I(inode)->mm_cred; } @@ -1510,27 +1510,13 @@ nfs4_proc_pathconf(struct nfs_server *se } static void -nfs4_restart_read(struct rpc_task *task) -{ - struct nfs_read_data *data = (struct nfs_read_data *)task->tk_calldata; - struct nfs_page *req; - - rpc_restart_call(task); - req = nfs_list_entry(data->pages.next); - if (req->wb_state) - nfs4_copy_stateid(&data->args.stateid, req->wb_state, req->wb_lockowner); - else - memcpy(&data->args.stateid, &zero_stateid, sizeof(data->args.stateid)); -} - -static void nfs4_read_done(struct rpc_task *task) { struct nfs_read_data *data = (struct nfs_read_data *) task->tk_calldata; struct inode *inode = data->inode; if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) { - task->tk_action = nfs4_restart_read; + rpc_restart_call(task); return; } if (task->tk_status > 0) @@ -1540,7 +1526,7 @@ nfs4_read_done(struct rpc_task *task) } static void -nfs4_proc_read_setup(struct nfs_read_data *data, unsigned int count) +nfs4_proc_read_setup(struct nfs_read_data *data) { struct rpc_task *task = &data->task; struct rpc_message msg = { @@ -1550,34 +1536,15 @@ nfs4_proc_read_setup(struct nfs_read_dat .rpc_cred = data->cred, }; struct inode *inode = data->inode; - struct nfs_page *req = nfs_list_entry(data->pages.next); int flags; - data->args.fh = NFS_FH(inode); - data->args.offset = req_offset(req); - data->args.pgbase = req->wb_pgbase; - data->args.pages = data->pagevec; - data->args.count = count; - data->res.fattr = &data->fattr; - data->res.count = count; - data->res.eof = 0; data->timestamp = jiffies; - data->lockowner = req->wb_lockowner; - if (req->wb_state) - nfs4_copy_stateid(&data->args.stateid, req->wb_state, req->wb_lockowner); - else - memcpy(&data->args.stateid, &zero_stateid, sizeof(data->args.stateid)); - /* N.B. Do we need to test? Never called for swapfile inode */ flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0); /* Finalize the task. */ rpc_init_task(task, NFS_CLIENT(inode), nfs4_read_done, flags); - task->tk_calldata = data; - /* Release requests */ - task->tk_release = nfs_readdata_release; - rpc_call_setup(task, &msg, 0); } diff -puN fs/nfs/nfs4xdr.c~nfs-02-small_rsize fs/nfs/nfs4xdr.c --- 25/fs/nfs/nfs4xdr.c~nfs-02-small_rsize 2004-03-14 15:12:31.179990392 -0800 +++ 25-akpm/fs/nfs/nfs4xdr.c 2004-03-14 15:12:31.192988416 -0800 @@ -868,14 +868,32 @@ encode_putrootfh(struct xdr_stream *xdr) return 0; } +static void +encode_stateid(struct xdr_stream *xdr, struct nfs4_state *state, fl_owner_t lockowner) +{ + extern nfs4_stateid zero_stateid; + nfs4_stateid stateid; + uint32_t *p; + + RESERVE_SPACE(16); + if (state != NULL) { + nfs4_copy_stateid(&stateid, state, lockowner); + WRITEMEM(stateid.data, sizeof(stateid.data)); + } else + WRITEMEM(zero_stateid.data, sizeof(zero_stateid.data)); +} + static int encode_read(struct xdr_stream *xdr, struct nfs_readargs *args) { uint32_t *p; - RESERVE_SPACE(32); + RESERVE_SPACE(4); WRITE32(OP_READ); - WRITEMEM(args->stateid.data, sizeof(args->stateid.data)); + + encode_stateid(xdr, args->state, args->lockowner); + + RESERVE_SPACE(12); WRITE64(args->offset); WRITE32(args->count); diff -puN fs/nfs/proc.c~nfs-02-small_rsize fs/nfs/proc.c --- 25/fs/nfs/proc.c~nfs-02-small_rsize 2004-03-14 15:12:31.180990240 -0800 +++ 25-akpm/fs/nfs/proc.c 2004-03-14 15:12:31.193988264 -0800 @@ -559,11 +559,10 @@ nfs_read_done(struct rpc_task *task) } static void -nfs_proc_read_setup(struct nfs_read_data *data, unsigned int count) +nfs_proc_read_setup(struct nfs_read_data *data) { struct rpc_task *task = &data->task; struct inode *inode = data->inode; - struct nfs_page *req; int flags; struct rpc_message msg = { .rpc_proc = &nfs_procedures[NFSPROC_READ], @@ -571,27 +570,13 @@ nfs_proc_read_setup(struct nfs_read_data .rpc_resp = &data->res, .rpc_cred = data->cred, }; - - req = nfs_list_entry(data->pages.next); - data->args.fh = NFS_FH(inode); - data->args.offset = req_offset(req); - data->args.pgbase = req->wb_pgbase; - data->args.pages = data->pagevec; - data->args.count = count; - data->res.fattr = &data->fattr; - data->res.count = count; - data->res.eof = 0; - + /* N.B. Do we need to test? Never called for swapfile inode */ flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0); /* Finalize the task. */ rpc_init_task(task, NFS_CLIENT(inode), nfs_read_done, flags); - task->tk_calldata = data; - /* Release requests */ - task->tk_release = nfs_readdata_release; - - rpc_call_setup(&data->task, &msg, 0); + rpc_call_setup(task, &msg, 0); } static void diff -puN fs/nfs/read.c~nfs-02-small_rsize fs/nfs/read.c --- 25/fs/nfs/read.c~nfs-02-small_rsize 2004-03-14 15:12:31.182989936 -0800 +++ 25-akpm/fs/nfs/read.c 2004-03-14 15:12:31.195987960 -0800 @@ -35,6 +35,8 @@ #define NFSDBG_FACILITY NFSDBG_PAGECACHE static int nfs_pagein_one(struct list_head *, struct inode *); +static void nfs_readpage_result_partial(struct nfs_read_data *, int); +static void nfs_readpage_result_full(struct nfs_read_data *, int); static kmem_cache_t *nfs_rdata_cachep; static mempool_t *nfs_rdata_mempool; @@ -57,12 +59,37 @@ static __inline__ void nfs_readdata_free mempool_free(p, nfs_rdata_mempool); } -void nfs_readdata_release(struct rpc_task *task) +static void nfs_readdata_release(struct rpc_task *task) { struct nfs_read_data *data = (struct nfs_read_data *)task->tk_calldata; nfs_readdata_free(data); } +static +unsigned int nfs_page_length(struct inode *inode, struct page *page) +{ + loff_t i_size = i_size_read(inode); + unsigned long idx; + + if (i_size <= 0) + return 0; + idx = (i_size - 1) >> PAGE_CACHE_SHIFT; + if (page->index > idx) + return 0; + if (page->index != idx) + return PAGE_CACHE_SIZE; + return 1 + ((i_size - 1) & (PAGE_CACHE_SIZE - 1)); +} + +static +int nfs_return_empty_page(struct page *page) +{ + memclear_highpage_flush(page, 0, PAGE_CACHE_SIZE); + SetPageUptodate(page); + unlock_page(page); + return 0; +} + /* * Read a page synchronously. */ @@ -78,6 +105,7 @@ nfs_readpage_sync(struct file *file, str .inode = inode, .args = { .fh = NFS_FH(inode), + .lockowner = current->files, .pages = &page, .pgbase = 0UL, .count = rsize, @@ -146,89 +174,208 @@ nfs_readpage_async(struct file *file, st { LIST_HEAD(one_request); struct nfs_page *new; + unsigned int len; - new = nfs_create_request(file, inode, page, 0, PAGE_CACHE_SIZE); + len = nfs_page_length(inode, page); + if (len == 0) + return nfs_return_empty_page(page); + new = nfs_create_request(file, inode, page, 0, len); if (IS_ERR(new)) { unlock_page(page); return PTR_ERR(new); } + if (len < PAGE_CACHE_SIZE) + memclear_highpage_flush(page, len, PAGE_CACHE_SIZE - len); + nfs_lock_request(new); nfs_list_add_request(new, &one_request); nfs_pagein_one(&one_request, inode); return 0; } +static void nfs_readpage_release(struct nfs_page *req) +{ + unlock_page(req->wb_page); + + nfs_clear_request(req); + nfs_release_request(req); + nfs_unlock_request(req); + + dprintk("NFS: read done (%s/%Ld %d@%Ld)\n", + req->wb_inode->i_sb->s_id, + (long long)NFS_FILEID(req->wb_inode), + req->wb_bytes, + (long long)req_offset(req)); +} + /* * Set up the NFS read request struct */ -static void -nfs_read_rpcsetup(struct list_head *head, struct nfs_read_data *data) +static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data, + unsigned int count, unsigned int offset) { struct inode *inode; - struct nfs_page *req; - struct page **pages; - unsigned int count; - pages = data->pagevec; - count = 0; - while (!list_empty(head)) { - req = nfs_list_entry(head->next); - nfs_list_remove_request(req); - nfs_list_add_request(req, &data->pages); - *pages++ = req->wb_page; - count += req->wb_bytes; - } - req = nfs_list_entry(data->pages.next); + data->req = req; data->inode = inode = req->wb_inode; data->cred = req->wb_cred; - NFS_PROTO(inode)->read_setup(data, count); + data->args.fh = NFS_FH(inode); + data->args.offset = req_offset(req) + offset; + data->args.pgbase = req->wb_pgbase + offset; + data->args.pages = data->pagevec; + data->args.count = count; + data->args.lockowner = req->wb_lockowner; + data->args.state = req->wb_state; + + data->res.fattr = &data->fattr; + data->res.count = count; + data->res.eof = 0; + + NFS_PROTO(inode)->read_setup(data); + + data->task.tk_calldata = data; + /* Release requests */ + data->task.tk_release = nfs_readdata_release; - dprintk("NFS: %4d initiated read call (req %s/%Ld, %u bytes @ offset %Lu.\n", + dprintk("NFS: %4d initiated read call (req %s/%Ld, %u bytes @ offset %Lu)\n", data->task.tk_pid, inode->i_sb->s_id, (long long)NFS_FILEID(inode), count, - (unsigned long long)req_offset(req)); + data->args.offset); } static void nfs_async_read_error(struct list_head *head) { struct nfs_page *req; - struct page *page; while (!list_empty(head)) { req = nfs_list_entry(head->next); - page = req->wb_page; nfs_list_remove_request(req); - SetPageError(page); - unlock_page(page); - nfs_clear_request(req); - nfs_release_request(req); - nfs_unlock_request(req); + SetPageError(req->wb_page); + nfs_readpage_release(req); } } -static int -nfs_pagein_one(struct list_head *head, struct inode *inode) +/* + * Start an async read operation + */ +static void nfs_execute_read(struct nfs_read_data *data) +{ + struct rpc_clnt *clnt = NFS_CLIENT(data->inode); + sigset_t oldset; + + rpc_clnt_sigmask(clnt, &oldset); + lock_kernel(); + rpc_execute(&data->task); + unlock_kernel(); + rpc_clnt_sigunmask(clnt, &oldset); +} + +/* + * Generate multiple requests to fill a single page. + * + * We optimize to reduce the number of read operations on the wire. If we + * detect that we're reading a page, or an area of a page, that is past the + * end of file, we do not generate NFS read operations but just clear the + * parts of the page that would have come back zero from the server anyway. + * + * We rely on the cached value of i_size to make this determination; another + * client can fill pages on the server past our cached end-of-file, but we + * won't see the new data until our attribute cache is updated. This is more + * or less conventional NFS client behavior. + */ +static int nfs_pagein_multi(struct list_head *head, struct inode *inode) +{ + struct nfs_page *req = nfs_list_entry(head->next); + struct page *page = req->wb_page; + struct nfs_read_data *data; + unsigned int rsize = NFS_SERVER(inode)->rsize; + unsigned int nbytes, offset; + int requests = 0; + LIST_HEAD(list); + + nfs_list_remove_request(req); + + nbytes = req->wb_bytes; + for(;;) { + data = nfs_readdata_alloc(); + if (!data) + goto out_bad; + list_add(&data->pages, &list); + requests++; + if (nbytes <= rsize) + break; + nbytes -= rsize; + } + atomic_set(&req->wb_complete, requests); + + ClearPageError(page); + offset = 0; + nbytes = req->wb_bytes; + do { + data = list_entry(list.next, struct nfs_read_data, pages); + list_del_init(&data->pages); + + data->pagevec[0] = page; + data->complete = nfs_readpage_result_partial; + + if (nbytes > rsize) { + nfs_read_rpcsetup(req, data, rsize, offset); + offset += rsize; + nbytes -= rsize; + } else { + nfs_read_rpcsetup(req, data, nbytes, offset); + nbytes = 0; + } + nfs_execute_read(data); + } while (nbytes != 0); + + return 0; + +out_bad: + while (!list_empty(&list)) { + data = list_entry(list.next, struct nfs_read_data, pages); + list_del(&data->pages); + nfs_readdata_free(data); + } + SetPageError(page); + nfs_readpage_release(req); + return -ENOMEM; +} + +static int nfs_pagein_one(struct list_head *head, struct inode *inode) { - struct rpc_clnt *clnt = NFS_CLIENT(inode); + struct nfs_page *req; + struct page **pages; struct nfs_read_data *data; - sigset_t oldset; + unsigned int count; + + if (NFS_SERVER(inode)->rsize < PAGE_CACHE_SIZE) + return nfs_pagein_multi(head, inode); data = nfs_readdata_alloc(); if (!data) goto out_bad; - nfs_read_rpcsetup(head, data); + pages = data->pagevec; + count = 0; + while (!list_empty(head)) { + req = nfs_list_entry(head->next); + nfs_list_remove_request(req); + nfs_list_add_request(req, &data->pages); + ClearPageError(req->wb_page); + *pages++ = req->wb_page; + count += req->wb_bytes; + } + req = nfs_list_entry(data->pages.next); + + data->complete = nfs_readpage_result_full; + nfs_read_rpcsetup(req, data, count, 0); - /* Start the async call */ - rpc_clnt_sigmask(clnt, &oldset); - lock_kernel(); - rpc_execute(&data->task); - unlock_kernel(); - rpc_clnt_sigunmask(clnt, &oldset); + nfs_execute_read(data); return 0; out_bad: nfs_async_read_error(head); @@ -258,55 +405,84 @@ nfs_pagein_list(struct list_head *head, } /* + * Handle a read reply that fills part of a page. + */ +static void nfs_readpage_result_partial(struct nfs_read_data *data, int status) +{ + struct nfs_page *req = data->req; + struct page *page = req->wb_page; + + if (status >= 0) { + unsigned int request = data->args.count; + unsigned int result = data->res.count; + + if (result < request) { + memclear_highpage_flush(page, + data->args.pgbase + result, + request - result); + if (!data->res.eof) + SetPageError(page); + } + } else + SetPageError(page); + + if (atomic_dec_and_test(&req->wb_complete)) { + if (!PageError(page)) + SetPageUptodate(page); + nfs_readpage_release(req); + } +} + +/* * This is the callback from RPC telling us whether a reply was * received or some error occurred (timeout or socket shutdown). */ -void -nfs_readpage_result(struct rpc_task *task) +static void nfs_readpage_result_full(struct nfs_read_data *data, int status) { - struct nfs_read_data *data = (struct nfs_read_data *)task->tk_calldata; unsigned int count = data->res.count; - dprintk("NFS: %4d nfs_readpage_result, (status %d)\n", - task->tk_pid, task->tk_status); - - NFS_FLAGS(data->inode) |= NFS_INO_INVALID_ATIME; while (!list_empty(&data->pages)) { struct nfs_page *req = nfs_list_entry(data->pages.next); struct page *page = req->wb_page; nfs_list_remove_request(req); - if (task->tk_status >= 0) { + if (status >= 0) { if (count < PAGE_CACHE_SIZE) { - memclear_highpage_flush(page, + if (count < req->wb_bytes) + memclear_highpage_flush(page, req->wb_pgbase + count, req->wb_bytes - count); - + if (!data->res.eof) + SetPageError(page); count = 0; } else count -= PAGE_CACHE_SIZE; SetPageUptodate(page); } else SetPageError(page); - unlock_page(page); - - dprintk("NFS: read (%s/%Ld %d@%Ld)\n", - req->wb_inode->i_sb->s_id, - (long long)NFS_FILEID(req->wb_inode), - req->wb_bytes, - (long long)req_offset(req)); - nfs_clear_request(req); - nfs_release_request(req); - nfs_unlock_request(req); + nfs_readpage_release(req); } } /* + * This is the callback from RPC telling us whether a reply was + * received or some error occurred (timeout or socket shutdown). + */ +void nfs_readpage_result(struct rpc_task *task) +{ + struct nfs_read_data *data = (struct nfs_read_data *)task->tk_calldata; + int status = task->tk_status; + + dprintk("NFS: %4d nfs_readpage_result, (status %d)\n", + task->tk_pid, status); + + NFS_FLAGS(data->inode) |= NFS_INO_INVALID_ATIME; + data->complete(data, status); +} + +/* * Read a page over NFS. - * We read the page synchronously in the following cases: - * - The NFS rsize is smaller than PAGE_CACHE_SIZE. We could kludge our way - * around this by creating several consecutive read requests, but - * that's hardly worth it. + * We read the page synchronously in the following case: * - The error flag is set for this page. This happens only when a * previous async read operation failed. */ @@ -329,7 +505,7 @@ nfs_readpage(struct file *file, struct p if (error) goto out_error; - if (!PageError(page) && NFS_SERVER(inode)->rsize >= PAGE_CACHE_SIZE) { + if (!IS_SYNC(inode)) { error = nfs_readpage_async(file, inode, page); goto out; } @@ -351,26 +527,25 @@ struct nfs_readdesc { }; static int -readpage_sync_filler(void *data, struct page *page) -{ - struct nfs_readdesc *desc = (struct nfs_readdesc *)data; - return nfs_readpage_sync(desc->filp, page->mapping->host, page); -} - -static int readpage_async_filler(void *data, struct page *page) { struct nfs_readdesc *desc = (struct nfs_readdesc *)data; struct inode *inode = page->mapping->host; struct nfs_page *new; + unsigned int len; nfs_wb_page(inode, page); - new = nfs_create_request(desc->filp, inode, page, 0, PAGE_CACHE_SIZE); + len = nfs_page_length(inode, page); + if (len == 0) + return nfs_return_empty_page(page); + new = nfs_create_request(desc->filp, inode, page, 0, len); if (IS_ERR(new)) { SetPageError(page); unlock_page(page); return PTR_ERR(new); } + if (len < PAGE_CACHE_SIZE) + memclear_highpage_flush(page, len, PAGE_CACHE_SIZE - len); nfs_lock_request(new); nfs_list_add_request(new, desc->head); return 0; @@ -385,14 +560,16 @@ nfs_readpages(struct file *filp, struct .filp = filp, .head = &head, }; - struct nfs_server *server = NFS_SERVER(mapping->host); - int is_sync = server->rsize < PAGE_CACHE_SIZE; + struct inode *inode = mapping->host; + struct nfs_server *server = NFS_SERVER(inode); int ret; - ret = read_cache_pages(mapping, pages, - is_sync ? readpage_sync_filler : - readpage_async_filler, - &desc); + dprintk("NFS: nfs_readpages (%s/%Ld %d)\n", + inode->i_sb->s_id, + (long long)NFS_FILEID(inode), + nr_pages); + + ret = read_cache_pages(mapping, pages, readpage_async_filler, &desc); if (!list_empty(&head)) { int err = nfs_pagein_list(&head, server->rpages); if (!ret) diff -puN include/linux/nfs_fs.h~nfs-02-small_rsize include/linux/nfs_fs.h --- 25/include/linux/nfs_fs.h~nfs-02-small_rsize 2004-03-14 15:12:31.183989784 -0800 +++ 25-akpm/include/linux/nfs_fs.h 2004-03-14 15:12:31.196987808 -0800 @@ -397,7 +397,6 @@ extern int nfs_readpages(struct file *, struct list_head *, unsigned); extern int nfs_pagein_list(struct list_head *, int); extern void nfs_readpage_result(struct rpc_task *); -extern void nfs_readdata_release(struct rpc_task *); /* * linux/fs/mount_clnt.c diff -puN include/linux/nfs_xdr.h~nfs-02-small_rsize include/linux/nfs_xdr.h --- 25/include/linux/nfs_xdr.h~nfs-02-small_rsize 2004-03-14 15:12:31.185989480 -0800 +++ 25-akpm/include/linux/nfs_xdr.h 2004-03-14 15:12:31.197987656 -0800 @@ -229,7 +229,8 @@ struct nfs_lockres { struct nfs_readargs { struct nfs_fh * fh; - nfs4_stateid stateid; + fl_owner_t lockowner; + struct nfs4_state * state; __u64 offset; __u32 count; unsigned int pgbase; @@ -663,7 +664,6 @@ struct nfs_read_data { struct rpc_task task; struct inode *inode; struct rpc_cred *cred; - fl_owner_t lockowner; struct nfs_fattr fattr; /* fattr storage */ struct list_head pages; /* Coalesced read requests */ struct nfs_page *req; /* multi ops per nfs_page */ @@ -741,7 +741,7 @@ struct nfs_rpc_ops { int (*pathconf) (struct nfs_server *, struct nfs_fh *, struct nfs_pathconf *); u32 * (*decode_dirent)(u32 *, struct nfs_entry *, int plus); - void (*read_setup) (struct nfs_read_data *, unsigned int count); + void (*read_setup) (struct nfs_read_data *); void (*write_setup) (struct nfs_write_data *, unsigned int count, int how); void (*commit_setup) (struct nfs_write_data *, u64 start, u32 len, int how); int (*file_open) (struct inode *, struct file *); _