From: Trond Myklebust <trond.myklebust@fys.uio.no> --=-zdRlnYP5ZtBt+QtNSgZx Content-Type: text/plain Content-Transfer-Encoding: 7bit NFSv2/v3/v4: Patch by Chuck Lever that add support for asynchronous writes even if wsize<PAGE_CACHE_SIZE. Cheers, Trond --=-zdRlnYP5ZtBt+QtNSgZx Content-Disposition: attachment; filename=linux-2.6.4-03-small_wsize.dif Content-Transfer-Encoding: base64 Content-Type: text/plain; name=linux-2.6.4-03-small_wsize.dif; charset=ISO-8859-1 IGZzL25mcy9kaXJlY3QuYyAgICAgICAgIHwgICAgMQ0KIGZzL25mcy9uZnMzcHJvYy5jICAgICAg IHwgICAzNCAtLS0tDQogZnMvbmZzL25mczRwcm9jLmMgICAgICAgfCAgIDY5ICstLS0tLS0tLQ0K IGZzL25mcy9uZnM0eGRyLmMgICAgICAgIHwgICAgNw0KIGZzL25mcy9wcm9jLmMgICAgICAgICAg IHwgICAyMSAtLQ0KIGZzL25mcy93cml0ZS5jICAgICAgICAgIHwgIDM2NCArKysrKysrKysrKysr KysrKysrKysrKysrKysrKysrKysrKy0tLS0tLS0tLS0tLS0NCiBpbmNsdWRlL2xpbnV4L25mc19m cy5oICB8ICAgIDINCiBpbmNsdWRlL2xpbnV4L25mc194ZHIuaCB8ICAgIDggLQ0KIDggZmlsZXMg Y2hhbmdlZCwgMjk0IGluc2VydGlvbnMoKyksIDIxMiBkZWxldGlvbnMoLSkNCg0KZGlmZiAtdSAt LXJlY3Vyc2l2ZSAtLW5ldy1maWxlIC0tc2hvdy1jLWZ1bmN0aW9uIGxpbnV4LTIuNi4zLTIwLXNt YWxsX3JzaXplL2ZzL25mcy9kaXJlY3QuYyBsaW51eC0yLjYuMy0yMS1zbWFsbF93c2l6ZS9mcy9u ZnMvZGlyZWN0LmMNCi0tLSBsaW51eC0yLjYuMy0yMC1zbWFsbF9yc2l6ZS9mcy9uZnMvZGlyZWN0 LmMJMjAwNC0wMy0wMSAxOTo0MTowNi4wMDAwMDAwMDAgLTA1MDANCisrKyBsaW51eC0yLjYuMy0y MS1zbWFsbF93c2l6ZS9mcy9uZnMvZGlyZWN0LmMJMjAwNC0wMy0wMSAxOTo0MToxNC4wMDAwMDAw MDAgLTA1MDANCkBAIC0yNTksNiArMjU5LDcgQEAgbmZzX2RpcmVjdF93cml0ZV9zZWcoc3RydWN0 IGlub2RlICppbm9kZQ0KIAkJLmlub2RlCQk9IGlub2RlLA0KIAkJLmFyZ3MJCT0gew0KIAkJCS5m aAkJPSBORlNfRkgoaW5vZGUpLA0KKwkJCS5sb2Nrb3duZXIJPSBjdXJyZW50LT5maWxlcywNCiAJ CX0sDQogCQkucmVzCQk9IHsNCiAJCQkuZmF0dHIJCT0gJndkYXRhLmZhdHRyLA0KZGlmZiAtdSAt LXJlY3Vyc2l2ZSAtLW5ldy1maWxlIC0tc2hvdy1jLWZ1bmN0aW9uIGxpbnV4LTIuNi4zLTIwLXNt YWxsX3JzaXplL2ZzL25mcy9uZnMzcHJvYy5jIGxpbnV4LTIuNi4zLTIxLXNtYWxsX3dzaXplL2Zz L25mcy9uZnMzcHJvYy5jDQotLS0gbGludXgtMi42LjMtMjAtc21hbGxfcnNpemUvZnMvbmZzL25m czNwcm9jLmMJMjAwNC0wMy0wMSAxOTo0MTowNi4wMDAwMDAwMDAgLTA1MDANCisrKyBsaW51eC0y LjYuMy0yMS1zbWFsbF93c2l6ZS9mcy9uZnMvbmZzM3Byb2MuYwkyMDA0LTAzLTAxIDE5OjQxOjE0 LjAwMDAwMDAwMCAtMDUwMA0KQEAgLTc2MywxMSArNzYzLDEwIEBAIG5mczNfd3JpdGVfZG9uZShz dHJ1Y3QgcnBjX3Rhc2sgKnRhc2spDQogfQ0KIA0KIHN0YXRpYyB2b2lkDQotbmZzM19wcm9jX3dy aXRlX3NldHVwKHN0cnVjdCBuZnNfd3JpdGVfZGF0YSAqZGF0YSwgdW5zaWduZWQgaW50IGNvdW50 LCBpbnQgaG93KQ0KK25mczNfcHJvY193cml0ZV9zZXR1cChzdHJ1Y3QgbmZzX3dyaXRlX2RhdGEg KmRhdGEsIGludCBob3cpDQogew0KIAlzdHJ1Y3QgcnBjX3Rhc2sJCSp0YXNrID0gJmRhdGEtPnRh c2s7DQogCXN0cnVjdCBpbm9kZQkJKmlub2RlID0gZGF0YS0+aW5vZGU7DQotCXN0cnVjdCBuZnNf cGFnZQkJKnJlcTsNCiAJaW50CQkJc3RhYmxlOw0KIAlpbnQJCQlmbGFnczsNCiAJc3RydWN0IHJw Y19tZXNzYWdlCW1zZyA9IHsNCkBAIC03ODQsMjggKzc4MywxNCBAQCBuZnMzX3Byb2Nfd3JpdGVf c2V0dXAoc3RydWN0IG5mc193cml0ZV9kDQogCQkJc3RhYmxlID0gTkZTX0RBVEFfU1lOQzsNCiAJ fSBlbHNlDQogCQlzdGFibGUgPSBORlNfVU5TVEFCTEU7DQotCQ0KLQlyZXEgPSBuZnNfbGlzdF9l bnRyeShkYXRhLT5wYWdlcy5uZXh0KTsNCi0JZGF0YS0+YXJncy5maCAgICAgPSBORlNfRkgoaW5v ZGUpOw0KLQlkYXRhLT5hcmdzLm9mZnNldCA9IHJlcV9vZmZzZXQocmVxKTsNCi0JZGF0YS0+YXJn cy5wZ2Jhc2UgPSByZXEtPndiX3BnYmFzZTsNCi0JZGF0YS0+YXJncy5jb3VudCAgPSBjb3VudDsN CiAJZGF0YS0+YXJncy5zdGFibGUgPSBzdGFibGU7DQotCWRhdGEtPmFyZ3MucGFnZXMgID0gZGF0 YS0+cGFnZXZlYzsNCi0JZGF0YS0+cmVzLmZhdHRyICAgPSAmZGF0YS0+ZmF0dHI7DQotCWRhdGEt PnJlcy5jb3VudCAgID0gY291bnQ7DQotCWRhdGEtPnJlcy52ZXJmICAgID0gJmRhdGEtPnZlcmY7 DQogDQogCS8qIFNldCB0aGUgaW5pdGlhbCBmbGFncyBmb3IgdGhlIHRhc2suICAqLw0KIAlmbGFn cyA9IChob3cgJiBGTFVTSF9TWU5DKSA/IDAgOiBSUENfVEFTS19BU1lOQzsNCiANCiAJLyogRmlu YWxpemUgdGhlIHRhc2suICovDQogCXJwY19pbml0X3Rhc2sodGFzaywgTkZTX0NMSUVOVChpbm9k ZSksIG5mczNfd3JpdGVfZG9uZSwgZmxhZ3MpOw0KLQl0YXNrLT50a19jYWxsZGF0YSA9IGRhdGE7 DQotCS8qIFJlbGVhc2UgcmVxdWVzdHMgKi8NCi0JdGFzay0+dGtfcmVsZWFzZSA9IG5mc193cml0 ZWRhdGFfcmVsZWFzZTsNCi0NCi0JcnBjX2NhbGxfc2V0dXAoJmRhdGEtPnRhc2ssICZtc2csIDAp Ow0KKwlycGNfY2FsbF9zZXR1cCh0YXNrLCAmbXNnLCAwKTsNCiB9DQogDQogc3RhdGljIHZvaWQN CkBAIC04MjIsNyArODA3LDcgQEAgbmZzM19jb21taXRfZG9uZShzdHJ1Y3QgcnBjX3Rhc2sgKnRh c2spDQogfQ0KIA0KIHN0YXRpYyB2b2lkDQotbmZzM19wcm9jX2NvbW1pdF9zZXR1cChzdHJ1Y3Qg bmZzX3dyaXRlX2RhdGEgKmRhdGEsIHU2NCBzdGFydCwgdTMyIGxlbiwgaW50IGhvdykNCituZnMz X3Byb2NfY29tbWl0X3NldHVwKHN0cnVjdCBuZnNfd3JpdGVfZGF0YSAqZGF0YSwgaW50IGhvdykN CiB7DQogCXN0cnVjdCBycGNfdGFzawkJKnRhc2sgPSAmZGF0YS0+dGFzazsNCiAJc3RydWN0IGlu b2RlCQkqaW5vZGUgPSBkYXRhLT5pbm9kZTsNCkBAIC04MzQsMjMgKzgxOSwxMiBAQCBuZnMzX3By b2NfY29tbWl0X3NldHVwKHN0cnVjdCBuZnNfd3JpdGVfDQogCQkucnBjX2NyZWQJPSBkYXRhLT5j cmVkLA0KIAl9Ow0KIA0KLQlkYXRhLT5hcmdzLmZoICAgICA9IE5GU19GSChkYXRhLT5pbm9kZSk7 DQotCWRhdGEtPmFyZ3Mub2Zmc2V0ID0gc3RhcnQ7DQotCWRhdGEtPmFyZ3MuY291bnQgID0gbGVu Ow0KLQlkYXRhLT5yZXMuY291bnQgICA9IGxlbjsNCi0JZGF0YS0+cmVzLmZhdHRyICAgPSAmZGF0 YS0+ZmF0dHI7DQotCWRhdGEtPnJlcy52ZXJmICAgID0gJmRhdGEtPnZlcmY7DQotCQ0KIAkvKiBT ZXQgdGhlIGluaXRpYWwgZmxhZ3MgZm9yIHRoZSB0YXNrLiAgKi8NCiAJZmxhZ3MgPSAoaG93ICYg RkxVU0hfU1lOQykgPyAwIDogUlBDX1RBU0tfQVNZTkM7DQogDQogCS8qIEZpbmFsaXplIHRoZSB0 YXNrLiAqLw0KIAlycGNfaW5pdF90YXNrKHRhc2ssIE5GU19DTElFTlQoaW5vZGUpLCBuZnMzX2Nv bW1pdF9kb25lLCBmbGFncyk7DQotCXRhc2stPnRrX2NhbGxkYXRhID0gZGF0YTsNCi0JLyogUmVs ZWFzZSByZXF1ZXN0cyAqLw0KLQl0YXNrLT50a19yZWxlYXNlID0gbmZzX2NvbW1pdF9yZWxlYXNl Ow0KLQkNCi0JcnBjX2NhbGxfc2V0dXAoJmRhdGEtPnRhc2ssICZtc2csIDApOw0KKwlycGNfY2Fs bF9zZXR1cCh0YXNrLCAmbXNnLCAwKTsNCiB9DQogDQogLyoNCmRpZmYgLXUgLS1yZWN1cnNpdmUg LS1uZXctZmlsZSAtLXNob3ctYy1mdW5jdGlvbiBsaW51eC0yLjYuMy0yMC1zbWFsbF9yc2l6ZS9m cy9uZnMvbmZzNHByb2MuYyBsaW51eC0yLjYuMy0yMS1zbWFsbF93c2l6ZS9mcy9uZnMvbmZzNHBy b2MuYw0KLS0tIGxpbnV4LTIuNi4zLTIwLXNtYWxsX3JzaXplL2ZzL25mcy9uZnM0cHJvYy5jCTIw MDQtMDMtMDEgMTk6NDE6MDYuMDAwMDAwMDAwIC0wNTAwDQorKysgbGludXgtMi42LjMtMjEtc21h bGxfd3NpemUvZnMvbmZzL25mczRwcm9jLmMJMjAwNC0wMy0wMSAxOTo0MToxNC4wMDAwMDAwMDAg LTA1MDANCkBAIC0xMTIzLDEwICsxMTIzLDEwIEBAIG5mczRfcHJvY193cml0ZShzdHJ1Y3QgbmZz X3dyaXRlX2RhdGEgKncNCiAJaWYgKGZpbHApIHsNCiAJCXN0cnVjdCBuZnM0X3N0YXRlICpzdGF0 ZTsNCiAJCXN0YXRlID0gKHN0cnVjdCBuZnM0X3N0YXRlICopZmlscC0+cHJpdmF0ZV9kYXRhOw0K LQkJbmZzNF9jb3B5X3N0YXRlaWQoJndkYXRhLT5hcmdzLnN0YXRlaWQsIHN0YXRlLCB3ZGF0YS0+ bG9ja293bmVyKTsNCisJCXdkYXRhLT5hcmdzLnN0YXRlID0gc3RhdGU7DQogCQltc2cucnBjX2Ny ZWQgPSBzdGF0ZS0+b3duZXItPnNvX2NyZWQ7DQogCX0gZWxzZSB7DQotCQltZW1jcHkoJndkYXRh LT5hcmdzLnN0YXRlaWQsICZ6ZXJvX3N0YXRlaWQsIHNpemVvZih3ZGF0YS0+YXJncy5zdGF0ZWlk KSk7DQorCQl3ZGF0YS0+YXJncy5zdGF0ZSA9IE5VTEw7DQogCQltc2cucnBjX2NyZWQgPSBORlNf SShpbm9kZSktPm1tX2NyZWQ7DQogCX0NCiANCkBAIC0xMTU1LDE1ICsxMTU1LDEwIEBAIG5mczRf cHJvY19jb21taXQoc3RydWN0IG5mc193cml0ZV9kYXRhICoNCiAJLyoNCiAJICogVHJ5IGZpcnN0 IHRvIHVzZSBPX1dST05MWSwgdGhlbiBPX1JEV1Igc3RhdGVpZC4NCiAJICovDQotCWlmIChmaWxw KSB7DQotCQlzdHJ1Y3QgbmZzNF9zdGF0ZSAqc3RhdGU7DQotCQlzdGF0ZSA9IChzdHJ1Y3QgbmZz NF9zdGF0ZSAqKWZpbHAtPnByaXZhdGVfZGF0YTsNCi0JCW5mczRfY29weV9zdGF0ZWlkKCZjZGF0 YS0+YXJncy5zdGF0ZWlkLCBzdGF0ZSwgY2RhdGEtPmxvY2tvd25lcik7DQotCQltc2cucnBjX2Ny ZWQgPSBzdGF0ZS0+b3duZXItPnNvX2NyZWQ7DQotCX0gZWxzZSB7DQotCQltZW1jcHkoJmNkYXRh LT5hcmdzLnN0YXRlaWQsICZ6ZXJvX3N0YXRlaWQsIHNpemVvZihjZGF0YS0+YXJncy5zdGF0ZWlk KSk7DQorCWlmIChmaWxwKQ0KKwkJbXNnLnJwY19jcmVkID0gKChzdHJ1Y3QgbmZzNF9zdGF0ZSAq KWZpbHAtPnByaXZhdGVfZGF0YSktPm93bmVyLT5zb19jcmVkOw0KKwllbHNlDQogCQltc2cucnBj X2NyZWQgPSBORlNfSShpbm9kZSktPm1tX2NyZWQ7DQotCX0NCiANCiAJZmF0dHItPnZhbGlkID0g MDsNCiAJc3RhdHVzID0gcnBjX2NhbGxfc3luYyhzZXJ2ZXItPmNsaWVudCwgJm1zZywgMCk7DQpA QCAtMTUzOCwyNyArMTUzMywxMyBAQCBuZnM0X3Byb2NfcmVhZF9zZXR1cChzdHJ1Y3QgbmZzX3Jl YWRfZGF0DQogfQ0KIA0KIHN0YXRpYyB2b2lkDQotbmZzNF9yZXN0YXJ0X3dyaXRlKHN0cnVjdCBy cGNfdGFzayAqdGFzaykNCi17DQotCXN0cnVjdCBuZnNfd3JpdGVfZGF0YSAqZGF0YSA9IChzdHJ1 Y3QgbmZzX3dyaXRlX2RhdGEgKil0YXNrLT50a19jYWxsZGF0YTsNCi0Jc3RydWN0IG5mc19wYWdl ICpyZXE7DQotDQotCXJwY19yZXN0YXJ0X2NhbGwodGFzayk7DQotCXJlcSA9IG5mc19saXN0X2Vu dHJ5KGRhdGEtPnBhZ2VzLm5leHQpOw0KLQlpZiAocmVxLT53Yl9zdGF0ZSkNCi0JCW5mczRfY29w eV9zdGF0ZWlkKCZkYXRhLT5hcmdzLnN0YXRlaWQsIHJlcS0+d2Jfc3RhdGUsIHJlcS0+d2JfbG9j a293bmVyKTsNCi0JZWxzZQ0KLQkJbWVtY3B5KCZkYXRhLT5hcmdzLnN0YXRlaWQsICZ6ZXJvX3N0 YXRlaWQsIHNpemVvZihkYXRhLT5hcmdzLnN0YXRlaWQpKTsNCi19DQotDQotc3RhdGljIHZvaWQN CiBuZnM0X3dyaXRlX2RvbmUoc3RydWN0IHJwY190YXNrICp0YXNrKQ0KIHsNCiAJc3RydWN0IG5m c193cml0ZV9kYXRhICpkYXRhID0gKHN0cnVjdCBuZnNfd3JpdGVfZGF0YSAqKSB0YXNrLT50a19j YWxsZGF0YTsNCiAJc3RydWN0IGlub2RlICppbm9kZSA9IGRhdGEtPmlub2RlOw0KIAkNCiAJaWYg KG5mczRfYXN5bmNfaGFuZGxlX2Vycm9yKHRhc2ssIE5GU19TRVJWRVIoaW5vZGUpKSA9PSAtRUFH QUlOKSB7DQotCQl0YXNrLT50a19hY3Rpb24gPSBuZnM0X3Jlc3RhcnRfd3JpdGU7DQorCQlycGNf cmVzdGFydF9jYWxsKHRhc2spOw0KIAkJcmV0dXJuOw0KIAl9DQogCWlmICh0YXNrLT50a19zdGF0 dXMgPj0gMCkNCkBAIC0xNTY4LDcgKzE1NDksNyBAQCBuZnM0X3dyaXRlX2RvbmUoc3RydWN0IHJw Y190YXNrICp0YXNrKQ0KIH0NCiANCiBzdGF0aWMgdm9pZA0KLW5mczRfcHJvY193cml0ZV9zZXR1 cChzdHJ1Y3QgbmZzX3dyaXRlX2RhdGEgKmRhdGEsIHVuc2lnbmVkIGludCBjb3VudCwgaW50IGhv dykNCituZnM0X3Byb2Nfd3JpdGVfc2V0dXAoc3RydWN0IG5mc193cml0ZV9kYXRhICpkYXRhLCBp bnQgaG93KQ0KIHsNCiAJc3RydWN0IHJwY190YXNrCSp0YXNrID0gJmRhdGEtPnRhc2s7DQogCXN0 cnVjdCBycGNfbWVzc2FnZSBtc2cgPSB7DQpAQCAtMTU3OCw3ICsxNTU5LDYgQEAgbmZzNF9wcm9j X3dyaXRlX3NldHVwKHN0cnVjdCBuZnNfd3JpdGVfZA0KIAkJLnJwY19jcmVkID0gZGF0YS0+Y3Jl ZCwNCiAJfTsNCiAJc3RydWN0IGlub2RlICppbm9kZSA9IGRhdGEtPmlub2RlOw0KLQlzdHJ1Y3Qg bmZzX3BhZ2UgKnJlcSA9IG5mc19saXN0X2VudHJ5KGRhdGEtPnBhZ2VzLm5leHQpOw0KIAlpbnQg c3RhYmxlOw0KIAlpbnQgZmxhZ3M7DQogCQ0KQEAgLTE1ODksMzMgKzE1NjksMTUgQEAgbmZzNF9w cm9jX3dyaXRlX3NldHVwKHN0cnVjdCBuZnNfd3JpdGVfZA0KIAkJCXN0YWJsZSA9IE5GU19EQVRB X1NZTkM7DQogCX0gZWxzZQ0KIAkJc3RhYmxlID0gTkZTX1VOU1RBQkxFOw0KLQ0KLQlkYXRhLT5h cmdzLmZoICAgICA9IE5GU19GSChpbm9kZSk7DQotCWRhdGEtPmFyZ3Mub2Zmc2V0ID0gcmVxX29m ZnNldChyZXEpOw0KLQlkYXRhLT5hcmdzLnBnYmFzZSA9IHJlcS0+d2JfcGdiYXNlOw0KLQlkYXRh LT5hcmdzLmNvdW50ICA9IGNvdW50Ow0KIAlkYXRhLT5hcmdzLnN0YWJsZSA9IHN0YWJsZTsNCi0J ZGF0YS0+YXJncy5wYWdlcyAgPSBkYXRhLT5wYWdldmVjOw0KLQlkYXRhLT5yZXMuZmF0dHIgICA9 ICZkYXRhLT5mYXR0cjsNCi0JZGF0YS0+cmVzLmNvdW50ICAgPSBjb3VudDsNCi0JZGF0YS0+cmVz LnZlcmYgICAgPSAmZGF0YS0+dmVyZjsNCi0JZGF0YS0+dGltZXN0YW1wICAgPSBqaWZmaWVzOw0K IA0KLQlkYXRhLT5sb2Nrb3duZXIgPSByZXEtPndiX2xvY2tvd25lcjsNCi0JaWYgKHJlcS0+d2Jf c3RhdGUpDQotCQluZnM0X2NvcHlfc3RhdGVpZCgmZGF0YS0+YXJncy5zdGF0ZWlkLCByZXEtPndi X3N0YXRlLCByZXEtPndiX2xvY2tvd25lcik7DQotCWVsc2UNCi0JCW1lbWNweSgmZGF0YS0+YXJn cy5zdGF0ZWlkLCAmemVyb19zdGF0ZWlkLCBzaXplb2YoZGF0YS0+YXJncy5zdGF0ZWlkKSk7DQor CWRhdGEtPnRpbWVzdGFtcCAgID0gamlmZmllczsNCiANCiAJLyogU2V0IHRoZSBpbml0aWFsIGZs YWdzIGZvciB0aGUgdGFzay4gICovDQogCWZsYWdzID0gKGhvdyAmIEZMVVNIX1NZTkMpID8gMCA6 IFJQQ19UQVNLX0FTWU5DOw0KIA0KIAkvKiBGaW5hbGl6ZSB0aGUgdGFzay4gKi8NCiAJcnBjX2lu aXRfdGFzayh0YXNrLCBORlNfQ0xJRU5UKGlub2RlKSwgbmZzNF93cml0ZV9kb25lLCBmbGFncyk7 DQotCXRhc2stPnRrX2NhbGxkYXRhID0gZGF0YTsNCi0JLyogUmVsZWFzZSByZXF1ZXN0cyAqLw0K LQl0YXNrLT50a19yZWxlYXNlID0gbmZzX3dyaXRlZGF0YV9yZWxlYXNlOw0KLQ0KIAlycGNfY2Fs bF9zZXR1cCh0YXNrLCAmbXNnLCAwKTsNCiB9DQogDQpAQCAtMTYyNiw3ICsxNTg4LDcgQEAgbmZz NF9jb21taXRfZG9uZShzdHJ1Y3QgcnBjX3Rhc2sgKnRhc2spDQogCXN0cnVjdCBpbm9kZSAqaW5v ZGUgPSBkYXRhLT5pbm9kZTsNCiAJDQogCWlmIChuZnM0X2FzeW5jX2hhbmRsZV9lcnJvcih0YXNr LCBORlNfU0VSVkVSKGlub2RlKSkgPT0gLUVBR0FJTikgew0KLQkJdGFzay0+dGtfYWN0aW9uID0g bmZzNF9yZXN0YXJ0X3dyaXRlOw0KKwkJcnBjX3Jlc3RhcnRfY2FsbCh0YXNrKTsNCiAJCXJldHVy bjsNCiAJfQ0KIAkvKiBDYWxsIGJhY2sgY29tbW9uIE5GUyB3cml0ZWJhY2sgcHJvY2Vzc2luZyAq Lw0KQEAgLTE2MzQsNyArMTU5Niw3IEBAIG5mczRfY29tbWl0X2RvbmUoc3RydWN0IHJwY190YXNr ICp0YXNrKQ0KIH0NCiANCiBzdGF0aWMgdm9pZA0KLW5mczRfcHJvY19jb21taXRfc2V0dXAoc3Ry dWN0IG5mc193cml0ZV9kYXRhICpkYXRhLCB1NjQgc3RhcnQsIHUzMiBsZW4sIGludCBob3cpDQor bmZzNF9wcm9jX2NvbW1pdF9zZXR1cChzdHJ1Y3QgbmZzX3dyaXRlX2RhdGEgKmRhdGEsIGludCBo b3cpDQogew0KIAlzdHJ1Y3QgcnBjX3Rhc2sJKnRhc2sgPSAmZGF0YS0+dGFzazsNCiAJc3RydWN0 IHJwY19tZXNzYWdlIG1zZyA9IHsNCkBAIC0xNjQ2LDIyICsxNjA4LDExIEBAIG5mczRfcHJvY19j b21taXRfc2V0dXAoc3RydWN0IG5mc193cml0ZV8NCiAJc3RydWN0IGlub2RlICppbm9kZSA9IGRh dGEtPmlub2RlOw0KIAlpbnQgZmxhZ3M7DQogCQ0KLQlkYXRhLT5hcmdzLmZoICAgICA9IE5GU19G SChkYXRhLT5pbm9kZSk7DQotCWRhdGEtPmFyZ3Mub2Zmc2V0ID0gc3RhcnQ7DQotCWRhdGEtPmFy Z3MuY291bnQgID0gbGVuOw0KLQlkYXRhLT5yZXMuY291bnQgICA9IGxlbjsNCi0JZGF0YS0+cmVz LmZhdHRyICAgPSAmZGF0YS0+ZmF0dHI7DQotCWRhdGEtPnJlcy52ZXJmICAgID0gJmRhdGEtPnZl cmY7DQotCQ0KIAkvKiBTZXQgdGhlIGluaXRpYWwgZmxhZ3MgZm9yIHRoZSB0YXNrLiAgKi8NCiAJ ZmxhZ3MgPSAoaG93ICYgRkxVU0hfU1lOQykgPyAwIDogUlBDX1RBU0tfQVNZTkM7DQogDQogCS8q IEZpbmFsaXplIHRoZSB0YXNrLiAqLw0KIAlycGNfaW5pdF90YXNrKHRhc2ssIE5GU19DTElFTlQo aW5vZGUpLCBuZnM0X2NvbW1pdF9kb25lLCBmbGFncyk7DQotCXRhc2stPnRrX2NhbGxkYXRhID0g ZGF0YTsNCi0JLyogUmVsZWFzZSByZXF1ZXN0cyAqLw0KLQl0YXNrLT50a19yZWxlYXNlID0gbmZz X2NvbW1pdF9yZWxlYXNlOw0KLQkNCiAJcnBjX2NhbGxfc2V0dXAodGFzaywgJm1zZywgMCk7CQ0K IH0NCiANCmRpZmYgLXUgLS1yZWN1cnNpdmUgLS1uZXctZmlsZSAtLXNob3ctYy1mdW5jdGlvbiBs aW51eC0yLjYuMy0yMC1zbWFsbF9yc2l6ZS9mcy9uZnMvbmZzNHhkci5jIGxpbnV4LTIuNi4zLTIx LXNtYWxsX3dzaXplL2ZzL25mcy9uZnM0eGRyLmMNCi0tLSBsaW51eC0yLjYuMy0yMC1zbWFsbF9y c2l6ZS9mcy9uZnMvbmZzNHhkci5jCTIwMDQtMDMtMDEgMTk6NDE6MDYuMDAwMDAwMDAwIC0wNTAw DQorKysgbGludXgtMi42LjMtMjEtc21hbGxfd3NpemUvZnMvbmZzL25mczR4ZHIuYwkyMDA0LTAz LTAxIDE5OjQxOjE0LjAwMDAwMDAwMCAtMDUwMA0KQEAgLTEwNzUsOSArMTA3NSwxMiBAQCBlbmNv ZGVfd3JpdGUoc3RydWN0IHhkcl9zdHJlYW0gKnhkciwgc3RyDQogew0KIAl1aW50MzJfdCAqcDsN CiANCi0JUkVTRVJWRV9TUEFDRSgzNik7DQorCVJFU0VSVkVfU1BBQ0UoNCk7DQogCVdSSVRFMzIo T1BfV1JJVEUpOw0KLQlXUklURU1FTShhcmdzLT5zdGF0ZWlkLmRhdGEsIHNpemVvZihhcmdzLT5z dGF0ZWlkLmRhdGEpKTsNCisNCisJZW5jb2RlX3N0YXRlaWQoeGRyLCBhcmdzLT5zdGF0ZSwgYXJn cy0+bG9ja293bmVyKTsNCisNCisJUkVTRVJWRV9TUEFDRSgxNik7DQogCVdSSVRFNjQoYXJncy0+ b2Zmc2V0KTsNCiAJV1JJVEUzMihhcmdzLT5zdGFibGUpOw0KIAlXUklURTMyKGFyZ3MtPmNvdW50 KTsNCmRpZmYgLXUgLS1yZWN1cnNpdmUgLS1uZXctZmlsZSAtLXNob3ctYy1mdW5jdGlvbiBsaW51 eC0yLjYuMy0yMC1zbWFsbF9yc2l6ZS9mcy9uZnMvcHJvYy5jIGxpbnV4LTIuNi4zLTIxLXNtYWxs X3dzaXplL2ZzL25mcy9wcm9jLmMNCi0tLSBsaW51eC0yLjYuMy0yMC1zbWFsbF9yc2l6ZS9mcy9u ZnMvcHJvYy5jCTIwMDQtMDMtMDEgMTk6NDE6MDYuMDAwMDAwMDAwIC0wNTAwDQorKysgbGludXgt Mi42LjMtMjEtc21hbGxfd3NpemUvZnMvbmZzL3Byb2MuYwkyMDA0LTAzLTAxIDE5OjQxOjE0LjAw MDAwMDAwMCAtMDUwMA0KQEAgLTU5MCwxMSArNTkwLDEwIEBAIG5mc193cml0ZV9kb25lKHN0cnVj dCBycGNfdGFzayAqdGFzaykNCiB9DQogDQogc3RhdGljIHZvaWQNCi1uZnNfcHJvY193cml0ZV9z ZXR1cChzdHJ1Y3QgbmZzX3dyaXRlX2RhdGEgKmRhdGEsIHVuc2lnbmVkIGludCBjb3VudCwgaW50 IGhvdykNCituZnNfcHJvY193cml0ZV9zZXR1cChzdHJ1Y3QgbmZzX3dyaXRlX2RhdGEgKmRhdGEs IGludCBob3cpDQogew0KIAlzdHJ1Y3QgcnBjX3Rhc2sJCSp0YXNrID0gJmRhdGEtPnRhc2s7DQog CXN0cnVjdCBpbm9kZQkJKmlub2RlID0gZGF0YS0+aW5vZGU7DQotCXN0cnVjdCBuZnNfcGFnZQkJ KnJlcTsNCiAJaW50CQkJZmxhZ3M7DQogCXN0cnVjdCBycGNfbWVzc2FnZQltc2cgPSB7DQogCQku cnBjX3Byb2MJPSAmbmZzX3Byb2NlZHVyZXNbTkZTUFJPQ19XUklURV0sDQpAQCAtNjA0LDMyICs2 MDMsMTggQEAgbmZzX3Byb2Nfd3JpdGVfc2V0dXAoc3RydWN0IG5mc193cml0ZV9kYQ0KIAl9Ow0K IA0KIAkvKiBOb3RlOiBORlN2MiBpZ25vcmVzIEBzdGFibGUgYW5kIGFsd2F5cyB1c2VzIE5GU19G SUxFX1NZTkMgKi8NCi0JDQotCXJlcSA9IG5mc19saXN0X2VudHJ5KGRhdGEtPnBhZ2VzLm5leHQp Ow0KLQlkYXRhLT5hcmdzLmZoICAgICA9IE5GU19GSChpbm9kZSk7DQotCWRhdGEtPmFyZ3Mub2Zm c2V0ID0gcmVxX29mZnNldChyZXEpOw0KLQlkYXRhLT5hcmdzLnBnYmFzZSA9IHJlcS0+d2JfcGdi YXNlOw0KLQlkYXRhLT5hcmdzLmNvdW50ICA9IGNvdW50Ow0KIAlkYXRhLT5hcmdzLnN0YWJsZSA9 IE5GU19GSUxFX1NZTkM7DQotCWRhdGEtPmFyZ3MucGFnZXMgID0gZGF0YS0+cGFnZXZlYzsNCi0J ZGF0YS0+cmVzLmZhdHRyICAgPSAmZGF0YS0+ZmF0dHI7DQotCWRhdGEtPnJlcy5jb3VudCAgID0g Y291bnQ7DQotCWRhdGEtPnJlcy52ZXJmICAgID0gJmRhdGEtPnZlcmY7DQogDQogCS8qIFNldCB0 aGUgaW5pdGlhbCBmbGFncyBmb3IgdGhlIHRhc2suICAqLw0KIAlmbGFncyA9IChob3cgJiBGTFVT SF9TWU5DKSA/IDAgOiBSUENfVEFTS19BU1lOQzsNCiANCiAJLyogRmluYWxpemUgdGhlIHRhc2su ICovDQogCXJwY19pbml0X3Rhc2sodGFzaywgTkZTX0NMSUVOVChpbm9kZSksIG5mc193cml0ZV9k b25lLCBmbGFncyk7DQotCXRhc2stPnRrX2NhbGxkYXRhID0gZGF0YTsNCi0JLyogUmVsZWFzZSBy ZXF1ZXN0cyAqLw0KLQl0YXNrLT50a19yZWxlYXNlID0gbmZzX3dyaXRlZGF0YV9yZWxlYXNlOw0K LQ0KLQlycGNfY2FsbF9zZXR1cCgmZGF0YS0+dGFzaywgJm1zZywgMCk7DQorCXJwY19jYWxsX3Nl dHVwKHRhc2ssICZtc2csIDApOw0KIH0NCiANCiBzdGF0aWMgdm9pZA0KLW5mc19wcm9jX2NvbW1p dF9zZXR1cChzdHJ1Y3QgbmZzX3dyaXRlX2RhdGEgKmRhdGEsIHU2NCBzdGFydCwgdTMyIGxlbiwg aW50IGhvdykNCituZnNfcHJvY19jb21taXRfc2V0dXAoc3RydWN0IG5mc193cml0ZV9kYXRhICpk YXRhLCBpbnQgaG93KQ0KIHsNCiAJQlVHKCk7DQogfQ0KZGlmZiAtdSAtLXJlY3Vyc2l2ZSAtLW5l dy1maWxlIC0tc2hvdy1jLWZ1bmN0aW9uIGxpbnV4LTIuNi4zLTIwLXNtYWxsX3JzaXplL2ZzL25m cy93cml0ZS5jIGxpbnV4LTIuNi4zLTIxLXNtYWxsX3dzaXplL2ZzL25mcy93cml0ZS5jDQotLS0g bGludXgtMi42LjMtMjAtc21hbGxfcnNpemUvZnMvbmZzL3dyaXRlLmMJMjAwNC0wMy0wMSAxOToz ODo1NC4wMDAwMDAwMDAgLTA1MDANCisrKyBsaW51eC0yLjYuMy0yMS1zbWFsbF93c2l6ZS9mcy9u ZnMvd3JpdGUuYwkyMDA0LTAzLTAzIDIwOjM5OjE2LjAwMDAwMDAwMCAtMDUwMA0KQEAgLTc0LDYg Kzc0LDggQEANCiBzdGF0aWMgc3RydWN0IG5mc19wYWdlICogbmZzX3VwZGF0ZV9yZXF1ZXN0KHN0 cnVjdCBmaWxlKiwgc3RydWN0IGlub2RlICosDQogCQkJCQkgICAgc3RydWN0IHBhZ2UgKiwNCiAJ CQkJCSAgICB1bnNpZ25lZCBpbnQsIHVuc2lnbmVkIGludCk7DQorc3RhdGljIHZvaWQgbmZzX3dy aXRlYmFja19kb25lX3BhcnRpYWwoc3RydWN0IG5mc193cml0ZV9kYXRhICosIGludCk7DQorc3Rh dGljIHZvaWQgbmZzX3dyaXRlYmFja19kb25lX2Z1bGwoc3RydWN0IG5mc193cml0ZV9kYXRhICos IGludCk7DQogDQogc3RhdGljIGttZW1fY2FjaGVfdCAqbmZzX3dkYXRhX2NhY2hlcDsNCiBzdGF0 aWMgbWVtcG9vbF90ICpuZnNfd2RhdGFfbWVtcG9vbDsNCkBAIC05NSw3ICs5Nyw3IEBAIHN0YXRp YyBfX2lubGluZV9fIHZvaWQgbmZzX3dyaXRlZGF0YV9mcmUNCiAJbWVtcG9vbF9mcmVlKHAsIG5m c193ZGF0YV9tZW1wb29sKTsNCiB9DQogDQotdm9pZCBuZnNfd3JpdGVkYXRhX3JlbGVhc2Uoc3Ry dWN0IHJwY190YXNrICp0YXNrKQ0KK3N0YXRpYyB2b2lkIG5mc193cml0ZWRhdGFfcmVsZWFzZShz dHJ1Y3QgcnBjX3Rhc2sgKnRhc2spDQogew0KIAlzdHJ1Y3QgbmZzX3dyaXRlX2RhdGEJKndkYXRh ID0gKHN0cnVjdCBuZnNfd3JpdGVfZGF0YSAqKXRhc2stPnRrX2NhbGxkYXRhOw0KIAluZnNfd3Jp dGVkYXRhX2ZyZWUod2RhdGEpOw0KQEAgLTExNywxMiArMTE5LDYgQEAgc3RhdGljIF9faW5saW5l X18gdm9pZCBuZnNfY29tbWl0X2ZyZWUocw0KIAltZW1wb29sX2ZyZWUocCwgbmZzX2NvbW1pdF9t ZW1wb29sKTsNCiB9DQogDQotdm9pZCBuZnNfY29tbWl0X3JlbGVhc2Uoc3RydWN0IHJwY190YXNr ICp0YXNrKQ0KLXsNCi0Jc3RydWN0IG5mc193cml0ZV9kYXRhCSp3ZGF0YSA9IChzdHJ1Y3QgbmZz X3dyaXRlX2RhdGEgKil0YXNrLT50a19jYWxsZGF0YTsNCi0JbmZzX2NvbW1pdF9mcmVlKHdkYXRh KTsNCi19DQotDQogLyogQWRqdXN0IHRoZSBmaWxlIGxlbmd0aCBpZiB3ZSdyZSB3cml0aW5nIGJl eW9uZCB0aGUgZW5kICovDQogc3RhdGljIHZvaWQgbmZzX2dyb3dfZmlsZShzdHJ1Y3QgcGFnZSAq cGFnZSwgdW5zaWduZWQgaW50IG9mZnNldCwgdW5zaWduZWQgaW50IGNvdW50KQ0KIHsNCkBAIC0x ODYsNiArMTgyLDcgQEAgbmZzX3dyaXRlcGFnZV9zeW5jKHN0cnVjdCBmaWxlICpmaWxlLCBzdA0K IAkJLmlub2RlCQk9IGlub2RlLA0KIAkJLmFyZ3MJCT0gew0KIAkJCS5maAkJPSBORlNfRkgoaW5v ZGUpLA0KKwkJCS5sb2Nrb3duZXIJPSBjdXJyZW50LT5maWxlcywNCiAJCQkucGFnZXMJCT0gJnBh Z2UsDQogCQkJLnN0YWJsZQkJPSBORlNfRklMRV9TWU5DLA0KIAkJCS5wZ2Jhc2UJCT0gb2Zmc2V0 LA0KQEAgLTMwMyw4ICszMDAsNyBAQCBuZnNfd3JpdGVwYWdlKHN0cnVjdCBwYWdlICpwYWdlLCBz dHJ1Y3QgDQogCQlnb3RvIG91dDsNCiBkb19pdDoNCiAJbG9ja19rZXJuZWwoKTsNCi0JaWYgKE5G U19TRVJWRVIoaW5vZGUpLT53c2l6ZSA+PSBQQUdFX0NBQ0hFX1NJWkUgJiYgIUlTX1NZTkMoaW5v ZGUpICYmDQotCQkJaW5vZGVfcmVmZXJlbmNlZCkgew0KKwlpZiAoIUlTX1NZTkMoaW5vZGUpICYm IGlub2RlX3JlZmVyZW5jZWQpIHsNCiAJCWVyciA9IG5mc193cml0ZXBhZ2VfYXN5bmMoTlVMTCwg aW5vZGUsIHBhZ2UsIDAsIG9mZnNldCk7DQogCQlpZiAoZXJyID49IDApDQogCQkJZXJyID0gMDsN CkBAIC0zNjksNyArMzY1LDcgQEAgbmZzX2lub2RlX2FkZF9yZXF1ZXN0KHN0cnVjdCBpbm9kZSAq aW5vZA0KIC8qDQogICogSW5zZXJ0IGEgd3JpdGUgcmVxdWVzdCBpbnRvIGFuIGlub2RlDQogICov DQotc3RhdGljIGlubGluZSB2b2lkDQorc3RhdGljIHZvaWQNCiBuZnNfaW5vZGVfcmVtb3ZlX3Jl cXVlc3Qoc3RydWN0IG5mc19wYWdlICpyZXEpDQogew0KIAlzdHJ1Y3QgbmZzX2lub2RlICpuZnNp Ow0KQEAgLTQyMCw3ICs0MTYsNyBAQCBuZnNfZmluZF9yZXF1ZXN0KHN0cnVjdCBpbm9kZSAqaW5v ZGUsIHVuDQogLyoNCiAgKiBBZGQgYSByZXF1ZXN0IHRvIHRoZSBpbm9kZSdzIGRpcnR5IGxpc3Qu DQogICovDQotc3RhdGljIGlubGluZSB2b2lkDQorc3RhdGljIHZvaWQNCiBuZnNfbWFya19yZXF1 ZXN0X2RpcnR5KHN0cnVjdCBuZnNfcGFnZSAqcmVxKQ0KIHsNCiAJc3RydWN0IGlub2RlICppbm9k ZSA9IHJlcS0+d2JfaW5vZGU7DQpAQCAtNDQ4LDcgKzQ0NCw3IEBAIG5mc19kaXJ0eV9yZXF1ZXN0 KHN0cnVjdCBuZnNfcGFnZSAqcmVxKQ0KIC8qDQogICogQWRkIGEgcmVxdWVzdCB0byB0aGUgaW5v ZGUncyBjb21taXQgbGlzdC4NCiAgKi8NCi1zdGF0aWMgaW5saW5lIHZvaWQNCitzdGF0aWMgdm9p ZA0KIG5mc19tYXJrX3JlcXVlc3RfY29tbWl0KHN0cnVjdCBuZnNfcGFnZSAqcmVxKQ0KIHsNCiAJ c3RydWN0IGlub2RlICppbm9kZSA9IHJlcS0+d2JfaW5vZGU7DQpAQCAtNjg0LDExICs2ODAsNyBA QCBuZnNfdXBkYXRlcGFnZShzdHJ1Y3QgZmlsZSAqZmlsZSwgc3RydWN0DQogCQlkZW50cnktPmRf cGFyZW50LT5kX25hbWUubmFtZSwgZGVudHJ5LT5kX25hbWUubmFtZSwNCiAJCWNvdW50LCAobG9u ZyBsb25nKShwYWdlX29mZnNldChwYWdlKSArb2Zmc2V0KSk7DQogDQotCS8qDQotCSAqIElmIHdz aXplIGlzIHNtYWxsZXIgdGhhbiBwYWdlIHNpemUsIHVwZGF0ZSBhbmQgd3JpdGUNCi0JICogcGFn ZSBzeW5jaHJvbm91c2x5Lg0KLQkgKi8NCi0JaWYgKE5GU19TRVJWRVIoaW5vZGUpLT53c2l6ZSA8 IFBBR0VfQ0FDSEVfU0laRSB8fCBJU19TWU5DKGlub2RlKSkgew0KKwlpZiAoSVNfU1lOQyhpbm9k ZSkpIHsNCiAJCXN0YXR1cyA9IG5mc193cml0ZXBhZ2Vfc3luYyhmaWxlLCBpbm9kZSwgcGFnZSwg b2Zmc2V0LCBjb3VudCk7DQogCQlpZiAoc3RhdHVzID4gMCkgew0KIAkJCWlmIChvZmZzZXQgPT0g MCAmJiBzdGF0dXMgPT0gUEFHRV9DQUNIRV9TSVpFKQ0KQEAgLTc1NSw0MyArNzQ3LDE0NiBAQCBk b25lOg0KIAlyZXR1cm4gc3RhdHVzOw0KIH0NCiANCitzdGF0aWMgdm9pZCBuZnNfd3JpdGVwYWdl X3JlbGVhc2Uoc3RydWN0IG5mc19wYWdlICpyZXEpDQorew0KKwllbmRfcGFnZV93cml0ZWJhY2so cmVxLT53Yl9wYWdlKTsNCisNCisjaWYgZGVmaW5lZChDT05GSUdfTkZTX1YzKSB8fCBkZWZpbmVk KENPTkZJR19ORlNfVjQpDQorCWlmICghUGFnZUVycm9yKHJlcS0+d2JfcGFnZSkpIHsNCisJCWlm IChORlNfTkVFRF9SRVNDSEVEKHJlcSkpIHsNCisJCQluZnNfbWFya19yZXF1ZXN0X2RpcnR5KHJl cSk7DQorCQkJZ290byBvdXQ7DQorCQl9IGVsc2UgaWYgKE5GU19ORUVEX0NPTU1JVChyZXEpKSB7 DQorCQkJbmZzX21hcmtfcmVxdWVzdF9jb21taXQocmVxKTsNCisJCQlnb3RvIG91dDsNCisJCX0N CisJfQ0KKwluZnNfaW5vZGVfcmVtb3ZlX3JlcXVlc3QocmVxKTsNCisNCitvdXQ6DQorCW5mc19j bGVhcl9jb21taXQocmVxKTsNCisJbmZzX2NsZWFyX3Jlc2NoZWR1bGUocmVxKTsNCisjZWxzZQ0K KwluZnNfaW5vZGVfcmVtb3ZlX3JlcXVlc3QocmVxKTsNCisjZW5kaWYNCisJbmZzX3VubG9ja19y ZXF1ZXN0KHJlcSk7DQorfQ0KKw0KIC8qDQogICogU2V0IHVwIHRoZSBhcmd1bWVudC9yZXN1bHQg c3RvcmFnZSByZXF1aXJlZCBmb3IgdGhlIFJQQyBjYWxsLg0KICAqLw0KLXN0YXRpYyB2b2lkDQot bmZzX3dyaXRlX3JwY3NldHVwKHN0cnVjdCBsaXN0X2hlYWQgKmhlYWQsIHN0cnVjdCBuZnNfd3Jp dGVfZGF0YSAqZGF0YSwgaW50IGhvdykNCitzdGF0aWMgdm9pZCBuZnNfd3JpdGVfcnBjc2V0dXAo c3RydWN0IG5mc19wYWdlICpyZXEsDQorCQlzdHJ1Y3QgbmZzX3dyaXRlX2RhdGEgKmRhdGEsDQor CQl1bnNpZ25lZCBpbnQgY291bnQsIHVuc2lnbmVkIGludCBvZmZzZXQsDQorCQlpbnQgaG93KQ0K IHsNCiAJc3RydWN0IHJwY190YXNrCQkqdGFzayA9ICZkYXRhLT50YXNrOw0KIAlzdHJ1Y3QgaW5v ZGUJCSppbm9kZTsNCi0Jc3RydWN0IG5mc19wYWdlCQkqcmVxOw0KLQlzdHJ1Y3QgcGFnZQkJKipw YWdlczsNCi0JdW5zaWduZWQgaW50CQljb3VudDsNCiANCiAJLyogU2V0IHVwIHRoZSBSUEMgYXJn dW1lbnQgYW5kIHJlcGx5IHN0cnVjdHMNCiAJICogTkI6IHRha2UgY2FyZSBub3QgdG8gbWVzcyBh Ym91dCB3aXRoIGRhdGEtPmNvbW1pdCBldCBhbC4gKi8NCiANCi0JcGFnZXMgPSBkYXRhLT5wYWdl dmVjOw0KLQljb3VudCA9IDA7DQotCXdoaWxlICghbGlzdF9lbXB0eShoZWFkKSkgew0KLQkJcmVx ID0gbmZzX2xpc3RfZW50cnkoaGVhZC0+bmV4dCk7DQotCQluZnNfbGlzdF9yZW1vdmVfcmVxdWVz dChyZXEpOw0KLQkJbmZzX2xpc3RfYWRkX3JlcXVlc3QocmVxLCAmZGF0YS0+cGFnZXMpOw0KLQkJ U2V0UGFnZVdyaXRlYmFjayhyZXEtPndiX3BhZ2UpOw0KLQkJKnBhZ2VzKysgPSByZXEtPndiX3Bh Z2U7DQotCQljb3VudCArPSByZXEtPndiX2J5dGVzOw0KLQl9DQotCXJlcSA9IG5mc19saXN0X2Vu dHJ5KGRhdGEtPnBhZ2VzLm5leHQpOw0KKwlkYXRhLT5yZXEgPSByZXE7DQogCWRhdGEtPmlub2Rl ID0gaW5vZGUgPSByZXEtPndiX2lub2RlOw0KIAlkYXRhLT5jcmVkID0gcmVxLT53Yl9jcmVkOw0K IA0KLQlORlNfUFJPVE8oaW5vZGUpLT53cml0ZV9zZXR1cChkYXRhLCBjb3VudCwgaG93KTsNCisJ ZGF0YS0+YXJncy5maCAgICAgPSBORlNfRkgoaW5vZGUpOw0KKwlkYXRhLT5hcmdzLm9mZnNldCA9 IHJlcV9vZmZzZXQocmVxKSArIG9mZnNldDsNCisJZGF0YS0+YXJncy5wZ2Jhc2UgPSByZXEtPndi X3BnYmFzZSArIG9mZnNldDsNCisJZGF0YS0+YXJncy5jb3VudCAgPSBjb3VudDsNCisJZGF0YS0+ YXJncy5wYWdlcyAgPSBkYXRhLT5wYWdldmVjOw0KKwlkYXRhLT5yZXMuZmF0dHIgICA9ICZkYXRh LT5mYXR0cjsNCisJZGF0YS0+cmVzLmNvdW50ICAgPSBjb3VudDsNCisJZGF0YS0+cmVzLnZlcmYg ICAgPSAmZGF0YS0+dmVyZjsNCisNCisJTkZTX1BST1RPKGlub2RlKS0+d3JpdGVfc2V0dXAoZGF0 YSwgaG93KTsNCisNCisJZGF0YS0+dGFzay50a19jYWxsZGF0YSA9IGRhdGE7DQorCS8qIFJlbGVh c2UgcmVxdWVzdHMgKi8NCisJZGF0YS0+dGFzay50a19yZWxlYXNlID0gbmZzX3dyaXRlZGF0YV9y ZWxlYXNlOw0KIA0KIAlkcHJpbnRrKCJORlM6ICU0ZCBpbml0aWF0ZWQgd3JpdGUgY2FsbCAocmVx ICVzLyVMZCwgJXUgYnl0ZXMgQCBvZmZzZXQgJUx1KVxuIiwNCiAJCXRhc2stPnRrX3BpZCwNCiAJ CWlub2RlLT5pX3NiLT5zX2lkLA0KIAkJKGxvbmcgbG9uZylORlNfRklMRUlEKGlub2RlKSwNCiAJ CWNvdW50LA0KLQkJKHVuc2lnbmVkIGxvbmcgbG9uZylyZXFfb2Zmc2V0KHJlcSkpOw0KKwkJZGF0 YS0+YXJncy5vZmZzZXQpOw0KK30NCisNCitzdGF0aWMgdm9pZCBuZnNfZXhlY3V0ZV93cml0ZShz dHJ1Y3QgbmZzX3dyaXRlX2RhdGEgKmRhdGEpDQorew0KKwlzdHJ1Y3QgcnBjX2NsbnQgKmNsbnQg PSBORlNfQ0xJRU5UKGRhdGEtPmlub2RlKTsNCisJc2lnc2V0X3Qgb2xkc2V0Ow0KKw0KKwlycGNf Y2xudF9zaWdtYXNrKGNsbnQsICZvbGRzZXQpOw0KKwlsb2NrX2tlcm5lbCgpOw0KKwlycGNfZXhl Y3V0ZSgmZGF0YS0+dGFzayk7DQorCXVubG9ja19rZXJuZWwoKTsNCisJcnBjX2NsbnRfc2lndW5t YXNrKGNsbnQsICZvbGRzZXQpOw0KK30NCisNCisvKg0KKyAqIEdlbmVyYXRlIG11bHRpcGxlIHNt YWxsIHJlcXVlc3RzIHRvIHdyaXRlIG91dCBhIHNpbmdsZQ0KKyAqIGNvbnRpZ3VvdXMgZGlydHkg YXJlYSBvbiBvbmUgcGFnZS4NCisgKi8NCitzdGF0aWMgaW50IG5mc19mbHVzaF9tdWx0aShzdHJ1 Y3QgbGlzdF9oZWFkICpoZWFkLCBzdHJ1Y3QgaW5vZGUgKmlub2RlLCBpbnQgaG93KQ0KK3sNCisJ c3RydWN0IG5mc19wYWdlICpyZXEgPSBuZnNfbGlzdF9lbnRyeShoZWFkLT5uZXh0KTsNCisJc3Ry dWN0IHBhZ2UgKnBhZ2UgPSByZXEtPndiX3BhZ2U7DQorCXN0cnVjdCBuZnNfd3JpdGVfZGF0YSAq ZGF0YTsNCisJdW5zaWduZWQgaW50IHdzaXplID0gTkZTX1NFUlZFUihpbm9kZSktPndzaXplOw0K Kwl1bnNpZ25lZCBpbnQgbmJ5dGVzLCBvZmZzZXQ7DQorCWludCByZXF1ZXN0cyA9IDA7DQorCUxJ U1RfSEVBRChsaXN0KTsNCisNCisJbmZzX2xpc3RfcmVtb3ZlX3JlcXVlc3QocmVxKTsNCisNCisJ bmJ5dGVzID0gcmVxLT53Yl9ieXRlczsNCisJZm9yICg7Oykgew0KKwkJZGF0YSA9IG5mc193cml0 ZWRhdGFfYWxsb2MoKTsNCisJCWlmICghZGF0YSkNCisJCQlnb3RvIG91dF9iYWQ7DQorCQlsaXN0 X2FkZCgmZGF0YS0+cGFnZXMsICZsaXN0KTsNCisJCXJlcXVlc3RzKys7DQorCQlpZiAobmJ5dGVz IDw9IHdzaXplKQ0KKwkJCWJyZWFrOw0KKwkJbmJ5dGVzIC09IHdzaXplOw0KKwl9DQorCWF0b21p Y19zZXQoJnJlcS0+d2JfY29tcGxldGUsIHJlcXVlc3RzKTsNCisNCisJQ2xlYXJQYWdlRXJyb3Io cGFnZSk7DQorCVNldFBhZ2VXcml0ZWJhY2socGFnZSk7DQorCW9mZnNldCA9IDA7DQorCW5ieXRl cyA9IHJlcS0+d2JfYnl0ZXM7DQorCWRvIHsNCisJCWRhdGEgPSBsaXN0X2VudHJ5KGxpc3QubmV4 dCwgc3RydWN0IG5mc193cml0ZV9kYXRhLCBwYWdlcyk7DQorCQlsaXN0X2RlbF9pbml0KCZkYXRh LT5wYWdlcyk7DQorDQorCQlkYXRhLT5wYWdldmVjWzBdID0gcGFnZTsNCisJCWRhdGEtPmNvbXBs ZXRlID0gbmZzX3dyaXRlYmFja19kb25lX3BhcnRpYWw7DQorDQorCQlpZiAobmJ5dGVzID4gd3Np emUpIHsNCisJCQluZnNfd3JpdGVfcnBjc2V0dXAocmVxLCBkYXRhLCB3c2l6ZSwgb2Zmc2V0LCBo b3cpOw0KKwkJCW9mZnNldCArPSB3c2l6ZTsNCisJCQluYnl0ZXMgLT0gd3NpemU7DQorCQl9IGVs c2Ugew0KKwkJCW5mc193cml0ZV9ycGNzZXR1cChyZXEsIGRhdGEsIG5ieXRlcywgb2Zmc2V0LCBo b3cpOw0KKwkJCW5ieXRlcyA9IDA7DQorCQl9DQorCQluZnNfZXhlY3V0ZV93cml0ZShkYXRhKTsN CisJfSB3aGlsZSAobmJ5dGVzICE9IDApOw0KKw0KKwlyZXR1cm4gMDsNCisNCitvdXRfYmFkOg0K Kwl3aGlsZSAoIWxpc3RfZW1wdHkoJmxpc3QpKSB7DQorCQlkYXRhID0gbGlzdF9lbnRyeShsaXN0 Lm5leHQsIHN0cnVjdCBuZnNfd3JpdGVfZGF0YSwgcGFnZXMpOw0KKwkJbGlzdF9kZWwoJmRhdGEt PnBhZ2VzKTsNCisJCW5mc193cml0ZWRhdGFfZnJlZShkYXRhKTsNCisJfQ0KKwluZnNfbWFya19y ZXF1ZXN0X2RpcnR5KHJlcSk7DQorCW5mc191bmxvY2tfcmVxdWVzdChyZXEpOw0KKwlyZXR1cm4g LUVOT01FTTsNCiB9DQogDQogLyoNCkBAIC04MDIsMjUgKzg5NywzOCBAQCBuZnNfd3JpdGVfcnBj c2V0dXAoc3RydWN0IGxpc3RfaGVhZCAqaGVhDQogICogVGhpcyBpcyB0aGUgY2FzZSBpZiBuZnNf dXBkYXRlcGFnZSBkZXRlY3RzIGEgY29uZmxpY3RpbmcgcmVxdWVzdA0KICAqIHRoYXQgaGFzIGJl ZW4gd3JpdHRlbiBidXQgbm90IGNvbW1pdHRlZC4NCiAgKi8NCi1zdGF0aWMgaW50DQotbmZzX2Zs dXNoX29uZShzdHJ1Y3QgbGlzdF9oZWFkICpoZWFkLCBzdHJ1Y3QgaW5vZGUgKmlub2RlLCBpbnQg aG93KQ0KK3N0YXRpYyBpbnQgbmZzX2ZsdXNoX29uZShzdHJ1Y3QgbGlzdF9oZWFkICpoZWFkLCBz dHJ1Y3QgaW5vZGUgKmlub2RlLCBpbnQgaG93KQ0KIHsNCi0Jc3RydWN0IHJwY19jbG50IAkqY2xu dCA9IE5GU19DTElFTlQoaW5vZGUpOw0KKwlzdHJ1Y3QgbmZzX3BhZ2UJCSpyZXE7DQorCXN0cnVj dCBwYWdlCQkqKnBhZ2VzOw0KIAlzdHJ1Y3QgbmZzX3dyaXRlX2RhdGEJKmRhdGE7DQotCXNpZ3Nl dF90CQlvbGRzZXQ7DQorCXVuc2lnbmVkIGludAkJY291bnQ7DQorDQorCWlmIChORlNfU0VSVkVS KGlub2RlKS0+d3NpemUgPCBQQUdFX0NBQ0hFX1NJWkUpDQorCQlyZXR1cm4gbmZzX2ZsdXNoX211 bHRpKGhlYWQsIGlub2RlLCBob3cpOw0KIA0KIAlkYXRhID0gbmZzX3dyaXRlZGF0YV9hbGxvYygp Ow0KIAlpZiAoIWRhdGEpDQogCQlnb3RvIG91dF9iYWQ7DQogDQorCXBhZ2VzID0gZGF0YS0+cGFn ZXZlYzsNCisJY291bnQgPSAwOw0KKwl3aGlsZSAoIWxpc3RfZW1wdHkoaGVhZCkpIHsNCisJCXJl cSA9IG5mc19saXN0X2VudHJ5KGhlYWQtPm5leHQpOw0KKwkJbmZzX2xpc3RfcmVtb3ZlX3JlcXVl c3QocmVxKTsNCisJCW5mc19saXN0X2FkZF9yZXF1ZXN0KHJlcSwgJmRhdGEtPnBhZ2VzKTsNCisJ CUNsZWFyUGFnZUVycm9yKHJlcS0+d2JfcGFnZSk7DQorCQlTZXRQYWdlV3JpdGViYWNrKHJlcS0+ d2JfcGFnZSk7DQorCQkqcGFnZXMrKyA9IHJlcS0+d2JfcGFnZTsNCisJCWNvdW50ICs9IHJlcS0+ d2JfYnl0ZXM7DQorCX0NCisJcmVxID0gbmZzX2xpc3RfZW50cnkoZGF0YS0+cGFnZXMubmV4dCk7 DQorDQorCWRhdGEtPmNvbXBsZXRlID0gbmZzX3dyaXRlYmFja19kb25lX2Z1bGw7DQogCS8qIFNl dCB1cCB0aGUgYXJndW1lbnQgc3RydWN0ICovDQotCW5mc193cml0ZV9ycGNzZXR1cChoZWFkLCBk YXRhLCBob3cpOw0KKwluZnNfd3JpdGVfcnBjc2V0dXAocmVxLCBkYXRhLCBjb3VudCwgMCwgaG93 KTsNCiANCi0JcnBjX2NsbnRfc2lnbWFzayhjbG50LCAmb2xkc2V0KTsNCi0JbG9ja19rZXJuZWwo KTsNCi0JcnBjX2V4ZWN1dGUoJmRhdGEtPnRhc2spOw0KLQl1bmxvY2tfa2VybmVsKCk7DQotCXJw Y19jbG50X3NpZ3VubWFzayhjbG50LCAmb2xkc2V0KTsNCisJbmZzX2V4ZWN1dGVfd3JpdGUoZGF0 YSk7DQogCXJldHVybiAwOw0KICBvdXRfYmFkOg0KIAl3aGlsZSAoIWxpc3RfZW1wdHkoaGVhZCkp IHsNCkBAIC04NTksMTggKzk2NywxMDcgQEAgbmZzX2ZsdXNoX2xpc3Qoc3RydWN0IGxpc3RfaGVh ZCAqaGVhZCwgaQ0KIAlyZXR1cm4gZXJyb3I7DQogfQ0KIA0KKy8qDQorICogSGFuZGxlIGEgd3Jp dGUgcmVwbHkgdGhhdCBmbHVzaGVkIHBhcnQgb2YgYSBwYWdlLg0KKyAqLw0KK3N0YXRpYyB2b2lk IG5mc193cml0ZWJhY2tfZG9uZV9wYXJ0aWFsKHN0cnVjdCBuZnNfd3JpdGVfZGF0YSAqZGF0YSwg aW50IHN0YXR1cykNCit7DQorCXN0cnVjdCBuZnNfcGFnZQkJKnJlcSA9IGRhdGEtPnJlcTsNCisJ c3RydWN0IHBhZ2UJCSpwYWdlID0gcmVxLT53Yl9wYWdlOw0KKw0KKwlkcHJpbnRrKCJORlM6IHdy aXRlICglcy8lTGQgJWRAJUxkKSIsDQorCQlyZXEtPndiX2lub2RlLT5pX3NiLT5zX2lkLA0KKwkJ KGxvbmcgbG9uZylORlNfRklMRUlEKHJlcS0+d2JfaW5vZGUpLA0KKwkJcmVxLT53Yl9ieXRlcywN CisJCShsb25nIGxvbmcpcmVxX29mZnNldChyZXEpKTsNCisNCisJaWYgKHN0YXR1cyA8IDApIHsN CisJCUNsZWFyUGFnZVVwdG9kYXRlKHBhZ2UpOw0KKwkJU2V0UGFnZUVycm9yKHBhZ2UpOw0KKwkJ aWYgKHJlcS0+d2JfZmlsZSkNCisJCQlyZXEtPndiX2ZpbGUtPmZfZXJyb3IgPSBzdGF0dXM7DQor CQlkcHJpbnRrKCIsIGVycm9yID0gJWRcbiIsIHN0YXR1cyk7DQorCX0gZWxzZSB7DQorI2lmIGRl ZmluZWQoQ09ORklHX05GU19WMykgfHwgZGVmaW5lZChDT05GSUdfTkZTX1Y0KQ0KKwkJaWYgKGRh dGEtPnZlcmYuY29tbWl0dGVkIDwgTkZTX0ZJTEVfU1lOQykgew0KKwkJCWlmICghTkZTX05FRURf Q09NTUlUKHJlcSkpIHsNCisJCQkJbmZzX2RlZmVyX2NvbW1pdChyZXEpOw0KKwkJCQltZW1jcHko JnJlcS0+d2JfdmVyZiwgJmRhdGEtPnZlcmYsIHNpemVvZihyZXEtPndiX3ZlcmYpKTsNCisJCQkJ ZHByaW50aygiIGRlZmVyIGNvbW1pdFxuIik7DQorCQkJfSBlbHNlIGlmIChtZW1jbXAoJnJlcS0+ d2JfdmVyZiwgJmRhdGEtPnZlcmYsIHNpemVvZihyZXEtPndiX3ZlcmYpKSkgew0KKwkJCQluZnNf ZGVmZXJfcmVzY2hlZHVsZShyZXEpOw0KKwkJCQlkcHJpbnRrKCIgc2VydmVyIHJlYm9vdCBkZXRl Y3RlZFxuIik7DQorCQkJfQ0KKwkJfSBlbHNlDQorI2VuZGlmDQorCQkJZHByaW50aygiIE9LXG4i KTsNCisJfQ0KKw0KKwlpZiAoYXRvbWljX2RlY19hbmRfdGVzdCgmcmVxLT53Yl9jb21wbGV0ZSkp DQorCQluZnNfd3JpdGVwYWdlX3JlbGVhc2UocmVxKTsNCit9DQorDQorLyoNCisgKiBIYW5kbGUg YSB3cml0ZSByZXBseSB0aGF0IGZsdXNoZXMgYSB3aG9sZSBwYWdlLg0KKyAqDQorICogRklYTUU6 IFRoZXJlIGlzIGFuIGluaGVyZW50IHJhY2Ugd2l0aCBpbnZhbGlkYXRlX2lub2RlX3BhZ2VzIGFu ZA0KKyAqCSAgd3JpdGViYWNrcyBzaW5jZSB0aGUgcGFnZS0+Y291bnQgaXMga2VwdCA+IDEgZm9y IGFzIGxvbmcNCisgKgkgIGFzIHRoZSBwYWdlIGhhcyBhIHdyaXRlIHJlcXVlc3QgcGVuZGluZy4N CisgKi8NCitzdGF0aWMgdm9pZCBuZnNfd3JpdGViYWNrX2RvbmVfZnVsbChzdHJ1Y3QgbmZzX3dy aXRlX2RhdGEgKmRhdGEsIGludCBzdGF0dXMpDQorew0KKwlzdHJ1Y3QgbmZzX3BhZ2UJCSpyZXE7 DQorCXN0cnVjdCBwYWdlCQkqcGFnZTsNCisNCisJLyogVXBkYXRlIGF0dHJpYnV0ZXMgYXMgcmVz dWx0IG9mIHdyaXRlYmFjay4gKi8NCisJd2hpbGUgKCFsaXN0X2VtcHR5KCZkYXRhLT5wYWdlcykp IHsNCisJCXJlcSA9IG5mc19saXN0X2VudHJ5KGRhdGEtPnBhZ2VzLm5leHQpOw0KKwkJbmZzX2xp c3RfcmVtb3ZlX3JlcXVlc3QocmVxKTsNCisJCXBhZ2UgPSByZXEtPndiX3BhZ2U7DQorDQorCQlk cHJpbnRrKCJORlM6IHdyaXRlICglcy8lTGQgJWRAJUxkKSIsDQorCQkJcmVxLT53Yl9pbm9kZS0+ aV9zYi0+c19pZCwNCisJCQkobG9uZyBsb25nKU5GU19GSUxFSUQocmVxLT53Yl9pbm9kZSksDQor CQkJcmVxLT53Yl9ieXRlcywNCisJCQkobG9uZyBsb25nKXJlcV9vZmZzZXQocmVxKSk7DQorDQor CQlpZiAoc3RhdHVzIDwgMCkgew0KKwkJCUNsZWFyUGFnZVVwdG9kYXRlKHBhZ2UpOw0KKwkJCVNl dFBhZ2VFcnJvcihwYWdlKTsNCisJCQlpZiAocmVxLT53Yl9maWxlKQ0KKwkJCQlyZXEtPndiX2Zp bGUtPmZfZXJyb3IgPSBzdGF0dXM7DQorCQkJZW5kX3BhZ2Vfd3JpdGViYWNrKHBhZ2UpOw0KKwkJ CW5mc19pbm9kZV9yZW1vdmVfcmVxdWVzdChyZXEpOw0KKwkJCWRwcmludGsoIiwgZXJyb3IgPSAl ZFxuIiwgc3RhdHVzKTsNCisJCQlnb3RvIG5leHQ7DQorCQl9DQorCQllbmRfcGFnZV93cml0ZWJh Y2socGFnZSk7DQorDQorI2lmIGRlZmluZWQoQ09ORklHX05GU19WMykgfHwgZGVmaW5lZChDT05G SUdfTkZTX1Y0KQ0KKwkJaWYgKGRhdGEtPmFyZ3Muc3RhYmxlICE9IE5GU19VTlNUQUJMRSB8fCBk YXRhLT52ZXJmLmNvbW1pdHRlZCA9PSBORlNfRklMRV9TWU5DKSB7DQorCQkJbmZzX2lub2RlX3Jl bW92ZV9yZXF1ZXN0KHJlcSk7DQorCQkJZHByaW50aygiIE9LXG4iKTsNCisJCQlnb3RvIG5leHQ7 DQorCQl9DQorCQltZW1jcHkoJnJlcS0+d2JfdmVyZiwgJmRhdGEtPnZlcmYsIHNpemVvZihyZXEt PndiX3ZlcmYpKTsNCisJCW5mc19tYXJrX3JlcXVlc3RfY29tbWl0KHJlcSk7DQorCQlkcHJpbnRr KCIgbWFya2VkIGZvciBjb21taXRcbiIpOw0KKyNlbHNlDQorCQluZnNfaW5vZGVfcmVtb3ZlX3Jl cXVlc3QocmVxKTsNCisjZW5kaWYNCisJbmV4dDoNCisJCW5mc191bmxvY2tfcmVxdWVzdChyZXEp Ow0KKwl9DQorfQ0KIA0KIC8qDQogICogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgd2hlbiB0aGUg V1JJVEUgY2FsbCBpcyBjb21wbGV0ZS4NCiAgKi8NCi12b2lkDQotbmZzX3dyaXRlYmFja19kb25l KHN0cnVjdCBycGNfdGFzayAqdGFzaykNCit2b2lkIG5mc193cml0ZWJhY2tfZG9uZShzdHJ1Y3Qg cnBjX3Rhc2sgKnRhc2spDQogew0KIAlzdHJ1Y3QgbmZzX3dyaXRlX2RhdGEJKmRhdGEgPSAoc3Ry dWN0IG5mc193cml0ZV9kYXRhICopIHRhc2stPnRrX2NhbGxkYXRhOw0KIAlzdHJ1Y3QgbmZzX3dy aXRlYXJncwkqYXJncCA9ICZkYXRhLT5hcmdzOw0KIAlzdHJ1Y3QgbmZzX3dyaXRlcmVzCSpyZXNw ID0gJmRhdGEtPnJlczsNCi0Jc3RydWN0IG5mc19wYWdlCQkqcmVxOw0KLQlzdHJ1Y3QgcGFnZQkJ KnBhZ2U7DQogDQogCWRwcmludGsoIk5GUzogJTRkIG5mc193cml0ZWJhY2tfZG9uZSAoc3RhdHVz ICVkKVxuIiwNCiAJCXRhc2stPnRrX3BpZCwgdGFzay0+dGtfc3RhdHVzKTsNCkBAIC05MTIsNTMg KzExMDksMjIgQEAgbmZzX3dyaXRlYmFja19kb25lKHN0cnVjdCBycGNfdGFzayAqdGFzaw0KIAkv Kg0KIAkgKiBQcm9jZXNzIHRoZSBuZnNfcGFnZSBsaXN0DQogCSAqLw0KLQl3aGlsZSAoIWxpc3Rf ZW1wdHkoJmRhdGEtPnBhZ2VzKSkgew0KLQkJcmVxID0gbmZzX2xpc3RfZW50cnkoZGF0YS0+cGFn ZXMubmV4dCk7DQotCQluZnNfbGlzdF9yZW1vdmVfcmVxdWVzdChyZXEpOw0KLQkJcGFnZSA9IHJl cS0+d2JfcGFnZTsNCisJZGF0YS0+Y29tcGxldGUoZGF0YSwgdGFzay0+dGtfc3RhdHVzKTsNCit9 DQogDQotCQlkcHJpbnRrKCJORlM6IHdyaXRlICglcy8lTGQgJWRAJUxkKSIsDQotCQkJcmVxLT53 Yl9pbm9kZS0+aV9zYi0+c19pZCwNCi0JCQkobG9uZyBsb25nKU5GU19GSUxFSUQocmVxLT53Yl9p bm9kZSksDQotCQkJcmVxLT53Yl9ieXRlcywNCi0JCQkobG9uZyBsb25nKXJlcV9vZmZzZXQocmVx KSk7DQotDQotCQlpZiAodGFzay0+dGtfc3RhdHVzIDwgMCkgew0KLQkJCUNsZWFyUGFnZVVwdG9k YXRlKHBhZ2UpOw0KLQkJCVNldFBhZ2VFcnJvcihwYWdlKTsNCi0JCQlpZiAocmVxLT53Yl9maWxl KQ0KLQkJCQlyZXEtPndiX2ZpbGUtPmZfZXJyb3IgPSB0YXNrLT50a19zdGF0dXM7DQotCQkJZW5k X3BhZ2Vfd3JpdGViYWNrKHBhZ2UpOw0KLQkJCW5mc19pbm9kZV9yZW1vdmVfcmVxdWVzdChyZXEp Ow0KLQkJCWRwcmludGsoIiwgZXJyb3IgPSAlZFxuIiwgdGFzay0+dGtfc3RhdHVzKTsNCi0JCQln b3RvIG5leHQ7DQotCQl9DQotCQllbmRfcGFnZV93cml0ZWJhY2socGFnZSk7DQogDQogI2lmIGRl ZmluZWQoQ09ORklHX05GU19WMykgfHwgZGVmaW5lZChDT05GSUdfTkZTX1Y0KQ0KLQkJaWYgKGFy Z3AtPnN0YWJsZSAhPSBORlNfVU5TVEFCTEUgfHwgZGF0YS0+dmVyZi5jb21taXR0ZWQgPT0gTkZT X0ZJTEVfU1lOQykgew0KLQkJCW5mc19pbm9kZV9yZW1vdmVfcmVxdWVzdChyZXEpOw0KLQkJCWRw cmludGsoIiBPS1xuIik7DQotCQkJZ290byBuZXh0Ow0KLQkJfQ0KLQkJbWVtY3B5KCZyZXEtPndi X3ZlcmYsICZkYXRhLT52ZXJmLCBzaXplb2YocmVxLT53Yl92ZXJmKSk7DQotCQluZnNfbWFya19y ZXF1ZXN0X2NvbW1pdChyZXEpOw0KLQkJZHByaW50aygiIG1hcmtlZCBmb3IgY29tbWl0XG4iKTsN Ci0jZWxzZQ0KLQkJbmZzX2lub2RlX3JlbW92ZV9yZXF1ZXN0KHJlcSk7DQotI2VuZGlmDQotCW5l eHQ6DQotCQluZnNfdW5sb2NrX3JlcXVlc3QocmVxKTsNCi0JfQ0KK3N0YXRpYyB2b2lkIG5mc19j b21taXRfcmVsZWFzZShzdHJ1Y3QgcnBjX3Rhc2sgKnRhc2spDQorew0KKwlzdHJ1Y3QgbmZzX3dy aXRlX2RhdGEJKndkYXRhID0gKHN0cnVjdCBuZnNfd3JpdGVfZGF0YSAqKXRhc2stPnRrX2NhbGxk YXRhOw0KKwluZnNfY29tbWl0X2ZyZWUod2RhdGEpOw0KIH0NCiANCi0NCi0jaWYgZGVmaW5lZChD T05GSUdfTkZTX1YzKSB8fCBkZWZpbmVkKENPTkZJR19ORlNfVjQpDQogLyoNCiAgKiBTZXQgdXAg dGhlIGFyZ3VtZW50L3Jlc3VsdCBzdG9yYWdlIHJlcXVpcmVkIGZvciB0aGUgUlBDIGNhbGwuDQog ICovDQotc3RhdGljIHZvaWQNCi1uZnNfY29tbWl0X3JwY3NldHVwKHN0cnVjdCBsaXN0X2hlYWQg KmhlYWQsIHN0cnVjdCBuZnNfd3JpdGVfZGF0YSAqZGF0YSwgaW50IGhvdykNCitzdGF0aWMgdm9p ZCBuZnNfY29tbWl0X3JwY3NldHVwKHN0cnVjdCBsaXN0X2hlYWQgKmhlYWQsDQorCQlzdHJ1Y3Qg bmZzX3dyaXRlX2RhdGEgKmRhdGEsIGludCBob3cpDQogew0KIAlzdHJ1Y3QgcnBjX3Rhc2sJCSp0 YXNrID0gJmRhdGEtPnRhc2s7DQogCXN0cnVjdCBuZnNfcGFnZQkJKmZpcnN0LCAqbGFzdDsNCkBA IC05ODcsNyArMTE1MywxOCBAQCBuZnNfY29tbWl0X3JwY3NldHVwKHN0cnVjdCBsaXN0X2hlYWQg KmhlDQogCWRhdGEtPmlub2RlCSAgPSBpbm9kZTsNCiAJZGF0YS0+Y3JlZAkgID0gZmlyc3QtPndi X2NyZWQ7DQogDQotCU5GU19QUk9UTyhpbm9kZSktPmNvbW1pdF9zZXR1cChkYXRhLCBzdGFydCwg bGVuLCBob3cpOw0KKwlkYXRhLT5hcmdzLmZoICAgICA9IE5GU19GSChkYXRhLT5pbm9kZSk7DQor CWRhdGEtPmFyZ3Mub2Zmc2V0ID0gc3RhcnQ7DQorCWRhdGEtPmFyZ3MuY291bnQgID0gbGVuOw0K KwlkYXRhLT5yZXMuY291bnQgICA9IGxlbjsNCisJZGF0YS0+cmVzLmZhdHRyICAgPSAmZGF0YS0+ ZmF0dHI7DQorCWRhdGEtPnJlcy52ZXJmICAgID0gJmRhdGEtPnZlcmY7DQorCQ0KKwlORlNfUFJP VE8oaW5vZGUpLT5jb21taXRfc2V0dXAoZGF0YSwgaG93KTsNCisNCisJZGF0YS0+dGFzay50a19j YWxsZGF0YSA9IGRhdGE7DQorCS8qIFJlbGVhc2UgcmVxdWVzdHMgKi8NCisJZGF0YS0+dGFzay50 a19yZWxlYXNlID0gbmZzX2NvbW1pdF9yZWxlYXNlOw0KIAkNCiAJZHByaW50aygiTkZTOiAlNGQg aW5pdGlhdGVkIGNvbW1pdCBjYWxsXG4iLCB0YXNrLT50a19waWQpOw0KIH0NCkBAIC05OTgsMTAg KzExNzUsOCBAQCBuZnNfY29tbWl0X3JwY3NldHVwKHN0cnVjdCBsaXN0X2hlYWQgKmhlDQogaW50 DQogbmZzX2NvbW1pdF9saXN0KHN0cnVjdCBsaXN0X2hlYWQgKmhlYWQsIGludCBob3cpDQogew0K LQlzdHJ1Y3QgcnBjX2NsbnQJCSpjbG50Ow0KIAlzdHJ1Y3QgbmZzX3dyaXRlX2RhdGEJKmRhdGE7 DQogCXN0cnVjdCBuZnNfcGFnZSAgICAgICAgICpyZXE7DQotCXNpZ3NldF90CQlvbGRzZXQ7DQog DQogCWRhdGEgPSBuZnNfY29tbWl0X2FsbG9jKCk7DQogDQpAQCAtMTAxMCwxMyArMTE4NSw4IEBA IG5mc19jb21taXRfbGlzdChzdHJ1Y3QgbGlzdF9oZWFkICpoZWFkLCANCiANCiAJLyogU2V0IHVw IHRoZSBhcmd1bWVudCBzdHJ1Y3QgKi8NCiAJbmZzX2NvbW1pdF9ycGNzZXR1cChoZWFkLCBkYXRh LCBob3cpOw0KLQljbG50ID0gTkZTX0NMSUVOVChkYXRhLT5pbm9kZSk7DQogDQotCXJwY19jbG50 X3NpZ21hc2soY2xudCwgJm9sZHNldCk7DQotCWxvY2tfa2VybmVsKCk7DQotCXJwY19leGVjdXRl KCZkYXRhLT50YXNrKTsNCi0JdW5sb2NrX2tlcm5lbCgpOw0KLQlycGNfY2xudF9zaWd1bm1hc2so Y2xudCwgJm9sZHNldCk7DQorCW5mc19leGVjdXRlX3dyaXRlKGRhdGEpOw0KIAlyZXR1cm4gMDsN CiAgb3V0X2JhZDoNCiAJd2hpbGUgKCFsaXN0X2VtcHR5KGhlYWQpKSB7DQpkaWZmIC11IC0tcmVj dXJzaXZlIC0tbmV3LWZpbGUgLS1zaG93LWMtZnVuY3Rpb24gbGludXgtMi42LjMtMjAtc21hbGxf cnNpemUvaW5jbHVkZS9saW51eC9uZnNfZnMuaCBsaW51eC0yLjYuMy0yMS1zbWFsbF93c2l6ZS9p bmNsdWRlL2xpbnV4L25mc19mcy5oDQotLS0gbGludXgtMi42LjMtMjAtc21hbGxfcnNpemUvaW5j bHVkZS9saW51eC9uZnNfZnMuaAkyMDA0LTAzLTAxIDE5OjQxOjA2LjAwMDAwMDAwMCAtMDUwMA0K KysrIGxpbnV4LTIuNi4zLTIxLXNtYWxsX3dzaXplL2luY2x1ZGUvbGludXgvbmZzX2ZzLmgJMjAw NC0wMy0wMSAxOTo0MToxNC4wMDAwMDAwMDAgLTA1MDANCkBAIC0zMzIsMTAgKzMzMiw4IEBAIGV4 dGVybiBpbnQgIG5mc193cml0ZXBhZ2VzKHN0cnVjdCBhZGRyZXMNCiBleHRlcm4gaW50ICBuZnNf Zmx1c2hfaW5jb21wYXRpYmxlKHN0cnVjdCBmaWxlICpmaWxlLCBzdHJ1Y3QgcGFnZSAqcGFnZSk7 DQogZXh0ZXJuIGludCAgbmZzX3VwZGF0ZXBhZ2Uoc3RydWN0IGZpbGUgKiwgc3RydWN0IHBhZ2Ug KiwgdW5zaWduZWQgaW50LCB1bnNpZ25lZCBpbnQpOw0KIGV4dGVybiB2b2lkIG5mc193cml0ZWJh Y2tfZG9uZShzdHJ1Y3QgcnBjX3Rhc2sgKnRhc2spOw0KLWV4dGVybiB2b2lkIG5mc193cml0ZWRh dGFfcmVsZWFzZShzdHJ1Y3QgcnBjX3Rhc2sgKnRhc2spOw0KIA0KICNpZiBkZWZpbmVkKENPTkZJ R19ORlNfVjMpIHx8IGRlZmluZWQoQ09ORklHX05GU19WNCkNCi1leHRlcm4gdm9pZCBuZnNfY29t bWl0X3JlbGVhc2Uoc3RydWN0IHJwY190YXNrICp0YXNrKTsNCiBleHRlcm4gdm9pZCBuZnNfY29t bWl0X2RvbmUoc3RydWN0IHJwY190YXNrICopOw0KICNlbmRpZg0KIA0KZGlmZiAtdSAtLXJlY3Vy c2l2ZSAtLW5ldy1maWxlIC0tc2hvdy1jLWZ1bmN0aW9uIGxpbnV4LTIuNi4zLTIwLXNtYWxsX3Jz aXplL2luY2x1ZGUvbGludXgvbmZzX3hkci5oIGxpbnV4LTIuNi4zLTIxLXNtYWxsX3dzaXplL2lu Y2x1ZGUvbGludXgvbmZzX3hkci5oDQotLS0gbGludXgtMi42LjMtMjAtc21hbGxfcnNpemUvaW5j bHVkZS9saW51eC9uZnNfeGRyLmgJMjAwNC0wMy0wMSAxOTo0MTowNi4wMDAwMDAwMDAgLTA1MDAN CisrKyBsaW51eC0yLjYuMy0yMS1zbWFsbF93c2l6ZS9pbmNsdWRlL2xpbnV4L25mc194ZHIuaAky MDA0LTAzLTAxIDE5OjQxOjE0LjAwMDAwMDAwMCAtMDUwMA0KQEAgLTI1Myw3ICsyNTMsOCBAQCBz dHJ1Y3QgbmZzX3JlYWRyZXMgew0KIA0KIHN0cnVjdCBuZnNfd3JpdGVhcmdzIHsNCiAJc3RydWN0 IG5mc19maCAqCQlmaDsNCi0JbmZzNF9zdGF0ZWlkCQlzdGF0ZWlkOw0KKwlmbF9vd25lcl90CQls b2Nrb3duZXI7DQorCXN0cnVjdCBuZnM0X3N0YXRlICoJc3RhdGU7DQogCV9fdTY0CQkJb2Zmc2V0 Ow0KIAlfX3UzMgkJCWNvdW50Ow0KIAllbnVtIG5mczNfc3RhYmxlX2hvdwlzdGFibGU7DQpAQCAt NjgxLDcgKzY4Miw2IEBAIHN0cnVjdCBuZnNfd3JpdGVfZGF0YSB7DQogCXN0cnVjdCBycGNfdGFz awkJdGFzazsNCiAJc3RydWN0IGlub2RlCQkqaW5vZGU7DQogCXN0cnVjdCBycGNfY3JlZAkJKmNy ZWQ7DQotCWZsX293bmVyX3QJCWxvY2tvd25lcjsNCiAJc3RydWN0IG5mc19mYXR0cglmYXR0cjsN CiAJc3RydWN0IG5mc193cml0ZXZlcmYJdmVyZjsNCiAJc3RydWN0IGxpc3RfaGVhZAlwYWdlczsJ CS8qIENvYWxlc2NlZCByZXF1ZXN0cyB3ZSB3aXNoIHRvIGZsdXNoICovDQpAQCAtNzQyLDggKzc0 Miw4IEBAIHN0cnVjdCBuZnNfcnBjX29wcyB7DQogCQkJICAgICBzdHJ1Y3QgbmZzX3BhdGhjb25m ICopOw0KIAl1MzIgKgkoKmRlY29kZV9kaXJlbnQpKHUzMiAqLCBzdHJ1Y3QgbmZzX2VudHJ5ICos IGludCBwbHVzKTsNCiAJdm9pZAkoKnJlYWRfc2V0dXApICAgKHN0cnVjdCBuZnNfcmVhZF9kYXRh ICopOw0KLQl2b2lkCSgqd3JpdGVfc2V0dXApICAoc3RydWN0IG5mc193cml0ZV9kYXRhICosIHVu c2lnbmVkIGludCBjb3VudCwgaW50IGhvdyk7DQotCXZvaWQJKCpjb21taXRfc2V0dXApIChzdHJ1 Y3QgbmZzX3dyaXRlX2RhdGEgKiwgdTY0IHN0YXJ0LCB1MzIgbGVuLCBpbnQgaG93KTsNCisJdm9p ZAkoKndyaXRlX3NldHVwKSAgKHN0cnVjdCBuZnNfd3JpdGVfZGF0YSAqLCBpbnQgaG93KTsNCisJ dm9pZAkoKmNvbW1pdF9zZXR1cCkgKHN0cnVjdCBuZnNfd3JpdGVfZGF0YSAqLCBpbnQgaG93KTsN CiAJaW50CSgqZmlsZV9vcGVuKSAgIChzdHJ1Y3QgaW5vZGUgKiwgc3RydWN0IGZpbGUgKik7DQog CWludAkoKmZpbGVfcmVsZWFzZSkgKHN0cnVjdCBpbm9kZSAqLCBzdHJ1Y3QgZmlsZSAqKTsNCiAJ dm9pZAkoKnJlcXVlc3RfaW5pdCkoc3RydWN0IG5mc19wYWdlICosIHN0cnVjdCBmaWxlICopOw0K --=-zdRlnYP5ZtBt+QtNSgZx-- --- 25-akpm/fs/nfs/direct.c | 1 25-akpm/fs/nfs/nfs3proc.c | 34 --- 25-akpm/fs/nfs/nfs4proc.c | 69 +------ 25-akpm/fs/nfs/nfs4xdr.c | 7 25-akpm/fs/nfs/proc.c | 21 -- 25-akpm/fs/nfs/write.c | 364 +++++++++++++++++++++++++++++----------- 25-akpm/include/linux/nfs_fs.h | 2 25-akpm/include/linux/nfs_xdr.h | 8 8 files changed, 294 insertions(+), 212 deletions(-) diff -puN fs/nfs/direct.c~nfs-03-small_wsize fs/nfs/direct.c --- 25/fs/nfs/direct.c~nfs-03-small_wsize 2004-03-14 15:12:33.186685328 -0800 +++ 25-akpm/fs/nfs/direct.c 2004-03-14 15:12:33.198683504 -0800 @@ -259,6 +259,7 @@ nfs_direct_write_seg(struct inode *inode .inode = inode, .args = { .fh = NFS_FH(inode), + .lockowner = current->files, }, .res = { .fattr = &wdata.fattr, diff -puN fs/nfs/nfs3proc.c~nfs-03-small_wsize fs/nfs/nfs3proc.c --- 25/fs/nfs/nfs3proc.c~nfs-03-small_wsize 2004-03-14 15:12:33.187685176 -0800 +++ 25-akpm/fs/nfs/nfs3proc.c 2004-03-14 15:12:33.199683352 -0800 @@ -763,11 +763,10 @@ nfs3_write_done(struct rpc_task *task) } static void -nfs3_proc_write_setup(struct nfs_write_data *data, unsigned int count, int how) +nfs3_proc_write_setup(struct nfs_write_data *data, int how) { struct rpc_task *task = &data->task; struct inode *inode = data->inode; - struct nfs_page *req; int stable; int flags; struct rpc_message msg = { @@ -784,28 +783,14 @@ nfs3_proc_write_setup(struct nfs_write_d stable = NFS_DATA_SYNC; } else stable = NFS_UNSTABLE; - - 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.count = count; data->args.stable = stable; - data->args.pages = data->pagevec; - data->res.fattr = &data->fattr; - data->res.count = count; - data->res.verf = &data->verf; /* Set the initial flags for the task. */ flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; /* Finalize the task. */ rpc_init_task(task, NFS_CLIENT(inode), nfs3_write_done, flags); - task->tk_calldata = data; - /* Release requests */ - task->tk_release = nfs_writedata_release; - - rpc_call_setup(&data->task, &msg, 0); + rpc_call_setup(task, &msg, 0); } static void @@ -822,7 +807,7 @@ nfs3_commit_done(struct rpc_task *task) } static void -nfs3_proc_commit_setup(struct nfs_write_data *data, u64 start, u32 len, int how) +nfs3_proc_commit_setup(struct nfs_write_data *data, int how) { struct rpc_task *task = &data->task; struct inode *inode = data->inode; @@ -834,23 +819,12 @@ nfs3_proc_commit_setup(struct nfs_write_ .rpc_cred = data->cred, }; - data->args.fh = NFS_FH(data->inode); - data->args.offset = start; - data->args.count = len; - data->res.count = len; - data->res.fattr = &data->fattr; - data->res.verf = &data->verf; - /* Set the initial flags for the task. */ flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; /* Finalize the task. */ rpc_init_task(task, NFS_CLIENT(inode), nfs3_commit_done, flags); - task->tk_calldata = data; - /* Release requests */ - task->tk_release = nfs_commit_release; - - rpc_call_setup(&data->task, &msg, 0); + rpc_call_setup(task, &msg, 0); } /* diff -puN fs/nfs/nfs4proc.c~nfs-03-small_wsize fs/nfs/nfs4proc.c --- 25/fs/nfs/nfs4proc.c~nfs-03-small_wsize 2004-03-14 15:12:33.189684872 -0800 +++ 25-akpm/fs/nfs/nfs4proc.c 2004-03-14 15:12:33.202682896 -0800 @@ -1134,10 +1134,10 @@ nfs4_proc_write(struct nfs_write_data *w if (filp) { struct nfs4_state *state; state = (struct nfs4_state *)filp->private_data; - nfs4_copy_stateid(&wdata->args.stateid, state, wdata->lockowner); + wdata->args.state = state; msg.rpc_cred = state->owner->so_cred; } else { - memcpy(&wdata->args.stateid, &zero_stateid, sizeof(wdata->args.stateid)); + wdata->args.state = NULL; msg.rpc_cred = NFS_I(inode)->mm_cred; } @@ -1166,15 +1166,10 @@ nfs4_proc_commit(struct nfs_write_data * /* * Try first to use O_WRONLY, then O_RDWR stateid. */ - if (filp) { - struct nfs4_state *state; - state = (struct nfs4_state *)filp->private_data; - nfs4_copy_stateid(&cdata->args.stateid, state, cdata->lockowner); - msg.rpc_cred = state->owner->so_cred; - } else { - memcpy(&cdata->args.stateid, &zero_stateid, sizeof(cdata->args.stateid)); + if (filp) + msg.rpc_cred = ((struct nfs4_state *)filp->private_data)->owner->so_cred; + else msg.rpc_cred = NFS_I(inode)->mm_cred; - } fattr->valid = 0; status = rpc_call_sync(server->client, &msg, 0); @@ -1549,27 +1544,13 @@ nfs4_proc_read_setup(struct nfs_read_dat } static void -nfs4_restart_write(struct rpc_task *task) -{ - struct nfs_write_data *data = (struct nfs_write_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_write_done(struct rpc_task *task) { struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata; struct inode *inode = data->inode; if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) { - task->tk_action = nfs4_restart_write; + rpc_restart_call(task); return; } if (task->tk_status >= 0) @@ -1579,7 +1560,7 @@ nfs4_write_done(struct rpc_task *task) } static void -nfs4_proc_write_setup(struct nfs_write_data *data, unsigned int count, int how) +nfs4_proc_write_setup(struct nfs_write_data *data, int how) { struct rpc_task *task = &data->task; struct rpc_message msg = { @@ -1589,7 +1570,6 @@ nfs4_proc_write_setup(struct nfs_write_d .rpc_cred = data->cred, }; struct inode *inode = data->inode; - struct nfs_page *req = nfs_list_entry(data->pages.next); int stable; int flags; @@ -1600,33 +1580,15 @@ nfs4_proc_write_setup(struct nfs_write_d stable = NFS_DATA_SYNC; } else stable = NFS_UNSTABLE; - - data->args.fh = NFS_FH(inode); - data->args.offset = req_offset(req); - data->args.pgbase = req->wb_pgbase; - data->args.count = count; data->args.stable = stable; - data->args.pages = data->pagevec; - data->res.fattr = &data->fattr; - data->res.count = count; - data->res.verf = &data->verf; - 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)); + data->timestamp = jiffies; /* Set the initial flags for the task. */ flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; /* Finalize the task. */ rpc_init_task(task, NFS_CLIENT(inode), nfs4_write_done, flags); - task->tk_calldata = data; - /* Release requests */ - task->tk_release = nfs_writedata_release; - rpc_call_setup(task, &msg, 0); } @@ -1637,7 +1599,7 @@ nfs4_commit_done(struct rpc_task *task) struct inode *inode = data->inode; if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) { - task->tk_action = nfs4_restart_write; + rpc_restart_call(task); return; } /* Call back common NFS writeback processing */ @@ -1645,7 +1607,7 @@ nfs4_commit_done(struct rpc_task *task) } static void -nfs4_proc_commit_setup(struct nfs_write_data *data, u64 start, u32 len, int how) +nfs4_proc_commit_setup(struct nfs_write_data *data, int how) { struct rpc_task *task = &data->task; struct rpc_message msg = { @@ -1657,22 +1619,11 @@ nfs4_proc_commit_setup(struct nfs_write_ struct inode *inode = data->inode; int flags; - data->args.fh = NFS_FH(data->inode); - data->args.offset = start; - data->args.count = len; - data->res.count = len; - data->res.fattr = &data->fattr; - data->res.verf = &data->verf; - /* Set the initial flags for the task. */ flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; /* Finalize the task. */ rpc_init_task(task, NFS_CLIENT(inode), nfs4_commit_done, flags); - task->tk_calldata = data; - /* Release requests */ - task->tk_release = nfs_commit_release; - rpc_call_setup(task, &msg, 0); } diff -puN fs/nfs/nfs4xdr.c~nfs-03-small_wsize fs/nfs/nfs4xdr.c --- 25/fs/nfs/nfs4xdr.c~nfs-03-small_wsize 2004-03-14 15:12:33.190684720 -0800 +++ 25-akpm/fs/nfs/nfs4xdr.c 2004-03-14 15:12:33.204682592 -0800 @@ -1075,9 +1075,12 @@ encode_write(struct xdr_stream *xdr, str { uint32_t *p; - RESERVE_SPACE(36); + RESERVE_SPACE(4); WRITE32(OP_WRITE); - WRITEMEM(args->stateid.data, sizeof(args->stateid.data)); + + encode_stateid(xdr, args->state, args->lockowner); + + RESERVE_SPACE(16); WRITE64(args->offset); WRITE32(args->stable); WRITE32(args->count); diff -puN fs/nfs/proc.c~nfs-03-small_wsize fs/nfs/proc.c --- 25/fs/nfs/proc.c~nfs-03-small_wsize 2004-03-14 15:12:33.192684416 -0800 +++ 25-akpm/fs/nfs/proc.c 2004-03-14 15:12:33.205682440 -0800 @@ -590,11 +590,10 @@ nfs_write_done(struct rpc_task *task) } static void -nfs_proc_write_setup(struct nfs_write_data *data, unsigned int count, int how) +nfs_proc_write_setup(struct nfs_write_data *data, int how) { 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_WRITE], @@ -604,32 +603,18 @@ nfs_proc_write_setup(struct nfs_write_da }; /* Note: NFSv2 ignores @stable and always uses NFS_FILE_SYNC */ - - 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.count = count; data->args.stable = NFS_FILE_SYNC; - data->args.pages = data->pagevec; - data->res.fattr = &data->fattr; - data->res.count = count; - data->res.verf = &data->verf; /* Set the initial flags for the task. */ flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; /* Finalize the task. */ rpc_init_task(task, NFS_CLIENT(inode), nfs_write_done, flags); - task->tk_calldata = data; - /* Release requests */ - task->tk_release = nfs_writedata_release; - - rpc_call_setup(&data->task, &msg, 0); + rpc_call_setup(task, &msg, 0); } static void -nfs_proc_commit_setup(struct nfs_write_data *data, u64 start, u32 len, int how) +nfs_proc_commit_setup(struct nfs_write_data *data, int how) { BUG(); } diff -puN fs/nfs/write.c~nfs-03-small_wsize fs/nfs/write.c --- 25/fs/nfs/write.c~nfs-03-small_wsize 2004-03-14 15:12:33.194684112 -0800 +++ 25-akpm/fs/nfs/write.c 2004-03-14 15:12:33.208681984 -0800 @@ -74,6 +74,8 @@ static struct nfs_page * nfs_update_request(struct file*, struct inode *, struct page *, unsigned int, unsigned int); +static void nfs_writeback_done_partial(struct nfs_write_data *, int); +static void nfs_writeback_done_full(struct nfs_write_data *, int); static kmem_cache_t *nfs_wdata_cachep; static mempool_t *nfs_wdata_mempool; @@ -95,7 +97,7 @@ static __inline__ void nfs_writedata_fre mempool_free(p, nfs_wdata_mempool); } -void nfs_writedata_release(struct rpc_task *task) +static void nfs_writedata_release(struct rpc_task *task) { struct nfs_write_data *wdata = (struct nfs_write_data *)task->tk_calldata; nfs_writedata_free(wdata); @@ -117,12 +119,6 @@ static __inline__ void nfs_commit_free(s mempool_free(p, nfs_commit_mempool); } -void nfs_commit_release(struct rpc_task *task) -{ - struct nfs_write_data *wdata = (struct nfs_write_data *)task->tk_calldata; - nfs_commit_free(wdata); -} - /* Adjust the file length if we're writing beyond the end */ static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int count) { @@ -186,6 +182,7 @@ nfs_writepage_sync(struct file *file, st .inode = inode, .args = { .fh = NFS_FH(inode), + .lockowner = current->files, .pages = &page, .stable = NFS_FILE_SYNC, .pgbase = offset, @@ -299,8 +296,7 @@ nfs_writepage(struct page *page, struct goto out; do_it: lock_kernel(); - if (NFS_SERVER(inode)->wsize >= PAGE_CACHE_SIZE && !IS_SYNC(inode) && - inode_referenced) { + if (!IS_SYNC(inode) && inode_referenced) { err = nfs_writepage_async(NULL, inode, page, 0, offset); if (err >= 0) err = 0; @@ -365,7 +361,7 @@ nfs_inode_add_request(struct inode *inod /* * Insert a write request into an inode */ -static inline void +static void nfs_inode_remove_request(struct nfs_page *req) { struct nfs_inode *nfsi; @@ -416,7 +412,7 @@ nfs_find_request(struct inode *inode, un /* * Add a request to the inode's dirty list. */ -static inline void +static void nfs_mark_request_dirty(struct nfs_page *req) { struct inode *inode = req->wb_inode; @@ -444,7 +440,7 @@ nfs_dirty_request(struct nfs_page *req) /* * Add a request to the inode's commit list. */ -static inline void +static void nfs_mark_request_commit(struct nfs_page *req) { struct inode *inode = req->wb_inode; @@ -680,11 +676,7 @@ nfs_updatepage(struct file *file, struct dentry->d_parent->d_name.name, dentry->d_name.name, count, (long long)(page_offset(page) +offset)); - /* - * If wsize is smaller than page size, update and write - * page synchronously. - */ - if (NFS_SERVER(inode)->wsize < PAGE_CACHE_SIZE || IS_SYNC(inode)) { + if (IS_SYNC(inode)) { status = nfs_writepage_sync(file, inode, page, offset, count); if (status > 0) { if (offset == 0 && status == PAGE_CACHE_SIZE) @@ -747,43 +739,146 @@ done: return status; } +static void nfs_writepage_release(struct nfs_page *req) +{ + end_page_writeback(req->wb_page); + +#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) + if (!PageError(req->wb_page)) { + if (NFS_NEED_RESCHED(req)) { + nfs_mark_request_dirty(req); + goto out; + } else if (NFS_NEED_COMMIT(req)) { + nfs_mark_request_commit(req); + goto out; + } + } + nfs_inode_remove_request(req); + +out: + nfs_clear_commit(req); + nfs_clear_reschedule(req); +#else + nfs_inode_remove_request(req); +#endif + nfs_unlock_request(req); +} + /* * Set up the argument/result storage required for the RPC call. */ -static void -nfs_write_rpcsetup(struct list_head *head, struct nfs_write_data *data, int how) +static void nfs_write_rpcsetup(struct nfs_page *req, + struct nfs_write_data *data, + unsigned int count, unsigned int offset, + int how) { struct rpc_task *task = &data->task; struct inode *inode; - struct nfs_page *req; - struct page **pages; - unsigned int count; /* Set up the RPC argument and reply structs * NB: take care not to mess about with data->commit et al. */ - 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); - SetPageWriteback(req->wb_page); - *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)->write_setup(data, count, how); + data->args.fh = NFS_FH(inode); + data->args.offset = req_offset(req) + offset; + data->args.pgbase = req->wb_pgbase + offset; + data->args.count = count; + data->args.pages = data->pagevec; + data->res.fattr = &data->fattr; + data->res.count = count; + data->res.verf = &data->verf; + + NFS_PROTO(inode)->write_setup(data, how); + + data->task.tk_calldata = data; + /* Release requests */ + data->task.tk_release = nfs_writedata_release; dprintk("NFS: %4d initiated write call (req %s/%Ld, %u bytes @ offset %Lu)\n", 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_execute_write(struct nfs_write_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 small requests to write out a single + * contiguous dirty area on one page. + */ +static int nfs_flush_multi(struct list_head *head, struct inode *inode, int how) +{ + struct nfs_page *req = nfs_list_entry(head->next); + struct page *page = req->wb_page; + struct nfs_write_data *data; + unsigned int wsize = NFS_SERVER(inode)->wsize; + unsigned int nbytes, offset; + int requests = 0; + LIST_HEAD(list); + + nfs_list_remove_request(req); + + nbytes = req->wb_bytes; + for (;;) { + data = nfs_writedata_alloc(); + if (!data) + goto out_bad; + list_add(&data->pages, &list); + requests++; + if (nbytes <= wsize) + break; + nbytes -= wsize; + } + atomic_set(&req->wb_complete, requests); + + ClearPageError(page); + SetPageWriteback(page); + offset = 0; + nbytes = req->wb_bytes; + do { + data = list_entry(list.next, struct nfs_write_data, pages); + list_del_init(&data->pages); + + data->pagevec[0] = page; + data->complete = nfs_writeback_done_partial; + + if (nbytes > wsize) { + nfs_write_rpcsetup(req, data, wsize, offset, how); + offset += wsize; + nbytes -= wsize; + } else { + nfs_write_rpcsetup(req, data, nbytes, offset, how); + nbytes = 0; + } + nfs_execute_write(data); + } while (nbytes != 0); + + return 0; + +out_bad: + while (!list_empty(&list)) { + data = list_entry(list.next, struct nfs_write_data, pages); + list_del(&data->pages); + nfs_writedata_free(data); + } + nfs_mark_request_dirty(req); + nfs_unlock_request(req); + return -ENOMEM; } /* @@ -794,25 +889,38 @@ nfs_write_rpcsetup(struct list_head *hea * This is the case if nfs_updatepage detects a conflicting request * that has been written but not committed. */ -static int -nfs_flush_one(struct list_head *head, struct inode *inode, int how) +static int nfs_flush_one(struct list_head *head, struct inode *inode, int how) { - struct rpc_clnt *clnt = NFS_CLIENT(inode); + struct nfs_page *req; + struct page **pages; struct nfs_write_data *data; - sigset_t oldset; + unsigned int count; + + if (NFS_SERVER(inode)->wsize < PAGE_CACHE_SIZE) + return nfs_flush_multi(head, inode, how); data = nfs_writedata_alloc(); if (!data) goto out_bad; + 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); + SetPageWriteback(req->wb_page); + *pages++ = req->wb_page; + count += req->wb_bytes; + } + req = nfs_list_entry(data->pages.next); + + data->complete = nfs_writeback_done_full; /* Set up the argument struct */ - nfs_write_rpcsetup(head, data, how); + nfs_write_rpcsetup(req, data, count, 0, how); - rpc_clnt_sigmask(clnt, &oldset); - lock_kernel(); - rpc_execute(&data->task); - unlock_kernel(); - rpc_clnt_sigunmask(clnt, &oldset); + nfs_execute_write(data); return 0; out_bad: while (!list_empty(head)) { @@ -851,18 +959,107 @@ nfs_flush_list(struct list_head *head, i return error; } +/* + * Handle a write reply that flushed part of a page. + */ +static void nfs_writeback_done_partial(struct nfs_write_data *data, int status) +{ + struct nfs_page *req = data->req; + struct page *page = req->wb_page; + + dprintk("NFS: write (%s/%Ld %d@%Ld)", + req->wb_inode->i_sb->s_id, + (long long)NFS_FILEID(req->wb_inode), + req->wb_bytes, + (long long)req_offset(req)); + + if (status < 0) { + ClearPageUptodate(page); + SetPageError(page); + if (req->wb_file) + req->wb_file->f_error = status; + dprintk(", error = %d\n", status); + } else { +#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) + if (data->verf.committed < NFS_FILE_SYNC) { + if (!NFS_NEED_COMMIT(req)) { + nfs_defer_commit(req); + memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf)); + dprintk(" defer commit\n"); + } else if (memcmp(&req->wb_verf, &data->verf, sizeof(req->wb_verf))) { + nfs_defer_reschedule(req); + dprintk(" server reboot detected\n"); + } + } else +#endif + dprintk(" OK\n"); + } + + if (atomic_dec_and_test(&req->wb_complete)) + nfs_writepage_release(req); +} + +/* + * Handle a write reply that flushes a whole page. + * + * FIXME: There is an inherent race with invalidate_inode_pages and + * writebacks since the page->count is kept > 1 for as long + * as the page has a write request pending. + */ +static void nfs_writeback_done_full(struct nfs_write_data *data, int status) +{ + struct nfs_page *req; + struct page *page; + + /* Update attributes as result of writeback. */ + while (!list_empty(&data->pages)) { + req = nfs_list_entry(data->pages.next); + nfs_list_remove_request(req); + page = req->wb_page; + + dprintk("NFS: write (%s/%Ld %d@%Ld)", + req->wb_inode->i_sb->s_id, + (long long)NFS_FILEID(req->wb_inode), + req->wb_bytes, + (long long)req_offset(req)); + + if (status < 0) { + ClearPageUptodate(page); + SetPageError(page); + if (req->wb_file) + req->wb_file->f_error = status; + end_page_writeback(page); + nfs_inode_remove_request(req); + dprintk(", error = %d\n", status); + goto next; + } + end_page_writeback(page); + +#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) + if (data->args.stable != NFS_UNSTABLE || data->verf.committed == NFS_FILE_SYNC) { + nfs_inode_remove_request(req); + dprintk(" OK\n"); + goto next; + } + memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf)); + nfs_mark_request_commit(req); + dprintk(" marked for commit\n"); +#else + nfs_inode_remove_request(req); +#endif + next: + nfs_unlock_request(req); + } +} /* * This function is called when the WRITE call is complete. */ -void -nfs_writeback_done(struct rpc_task *task) +void nfs_writeback_done(struct rpc_task *task) { struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata; struct nfs_writeargs *argp = &data->args; struct nfs_writeres *resp = &data->res; - struct nfs_page *req; - struct page *page; dprintk("NFS: %4d nfs_writeback_done (status %d)\n", task->tk_pid, task->tk_status); @@ -904,53 +1101,22 @@ nfs_writeback_done(struct rpc_task *task /* * Process the nfs_page list */ - while (!list_empty(&data->pages)) { - req = nfs_list_entry(data->pages.next); - nfs_list_remove_request(req); - page = req->wb_page; + data->complete(data, task->tk_status); +} - dprintk("NFS: write (%s/%Ld %d@%Ld)", - req->wb_inode->i_sb->s_id, - (long long)NFS_FILEID(req->wb_inode), - req->wb_bytes, - (long long)req_offset(req)); - - if (task->tk_status < 0) { - ClearPageUptodate(page); - SetPageError(page); - if (req->wb_file) - req->wb_file->f_error = task->tk_status; - end_page_writeback(page); - nfs_inode_remove_request(req); - dprintk(", error = %d\n", task->tk_status); - goto next; - } - end_page_writeback(page); #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) - if (argp->stable != NFS_UNSTABLE || data->verf.committed == NFS_FILE_SYNC) { - nfs_inode_remove_request(req); - dprintk(" OK\n"); - goto next; - } - memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf)); - nfs_mark_request_commit(req); - dprintk(" marked for commit\n"); -#else - nfs_inode_remove_request(req); -#endif - next: - nfs_unlock_request(req); - } +static void nfs_commit_release(struct rpc_task *task) +{ + struct nfs_write_data *wdata = (struct nfs_write_data *)task->tk_calldata; + nfs_commit_free(wdata); } - -#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) /* * Set up the argument/result storage required for the RPC call. */ -static void -nfs_commit_rpcsetup(struct list_head *head, struct nfs_write_data *data, int how) +static void nfs_commit_rpcsetup(struct list_head *head, + struct nfs_write_data *data, int how) { struct rpc_task *task = &data->task; struct nfs_page *first, *last; @@ -979,7 +1145,18 @@ nfs_commit_rpcsetup(struct list_head *he data->inode = inode; data->cred = first->wb_cred; - NFS_PROTO(inode)->commit_setup(data, start, len, how); + data->args.fh = NFS_FH(data->inode); + data->args.offset = start; + data->args.count = len; + data->res.count = len; + data->res.fattr = &data->fattr; + data->res.verf = &data->verf; + + NFS_PROTO(inode)->commit_setup(data, how); + + data->task.tk_calldata = data; + /* Release requests */ + data->task.tk_release = nfs_commit_release; dprintk("NFS: %4d initiated commit call\n", task->tk_pid); } @@ -990,10 +1167,8 @@ nfs_commit_rpcsetup(struct list_head *he int nfs_commit_list(struct list_head *head, int how) { - struct rpc_clnt *clnt; struct nfs_write_data *data; struct nfs_page *req; - sigset_t oldset; data = nfs_commit_alloc(); @@ -1002,13 +1177,8 @@ nfs_commit_list(struct list_head *head, /* Set up the argument struct */ nfs_commit_rpcsetup(head, data, how); - clnt = NFS_CLIENT(data->inode); - rpc_clnt_sigmask(clnt, &oldset); - lock_kernel(); - rpc_execute(&data->task); - unlock_kernel(); - rpc_clnt_sigunmask(clnt, &oldset); + nfs_execute_write(data); return 0; out_bad: while (!list_empty(head)) { diff -puN include/linux/nfs_fs.h~nfs-03-small_wsize include/linux/nfs_fs.h --- 25/include/linux/nfs_fs.h~nfs-03-small_wsize 2004-03-14 15:12:33.195683960 -0800 +++ 25-akpm/include/linux/nfs_fs.h 2004-03-14 15:12:33.209681832 -0800 @@ -335,10 +335,8 @@ extern int nfs_writepages(struct addres extern int nfs_flush_incompatible(struct file *file, struct page *page); extern int nfs_updatepage(struct file *, struct page *, unsigned int, unsigned int); extern void nfs_writeback_done(struct rpc_task *task); -extern void nfs_writedata_release(struct rpc_task *task); #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) -extern void nfs_commit_release(struct rpc_task *task); extern void nfs_commit_done(struct rpc_task *); #endif diff -puN include/linux/nfs_xdr.h~nfs-03-small_wsize include/linux/nfs_xdr.h --- 25/include/linux/nfs_xdr.h~nfs-03-small_wsize 2004-03-14 15:12:33.196683808 -0800 +++ 25-akpm/include/linux/nfs_xdr.h 2004-03-14 15:12:33.210681680 -0800 @@ -253,7 +253,8 @@ struct nfs_readres { struct nfs_writeargs { struct nfs_fh * fh; - nfs4_stateid stateid; + fl_owner_t lockowner; + struct nfs4_state * state; __u64 offset; __u32 count; enum nfs3_stable_how stable; @@ -681,7 +682,6 @@ struct nfs_write_data { struct rpc_task task; struct inode *inode; struct rpc_cred *cred; - fl_owner_t lockowner; struct nfs_fattr fattr; struct nfs_writeverf verf; struct list_head pages; /* Coalesced requests we wish to flush */ @@ -742,8 +742,8 @@ struct nfs_rpc_ops { struct nfs_pathconf *); u32 * (*decode_dirent)(u32 *, struct nfs_entry *, int plus); 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); + void (*write_setup) (struct nfs_write_data *, int how); + void (*commit_setup) (struct nfs_write_data *, int how); int (*file_open) (struct inode *, struct file *); int (*file_release) (struct inode *, struct file *); void (*request_init)(struct nfs_page *, struct file *); _