From: Trond Myklebust --=-FFtuzYZJrfmt3IifntWE Content-Type: text/plain Content-Transfer-Encoding: 7bit NFSv2/v3/v4: Deal with the case where the server reads/writes fewer bytes than we originally requested due to resource limitations etc. Cheers, Trond --=-FFtuzYZJrfmt3IifntWE Content-Disposition: attachment; filename=linux-2.6.4-08-short_rw.dif Content-Transfer-Encoding: base64 Content-Type: text/plain; name=linux-2.6.4-08-short_rw.dif; charset=ISO-8859-1 IHJlYWQuYyAgfCAgIDE5ICsrKysrKysrKysrKysrKy0tLS0NCiB3cml0ZS5jIHwgICA0NSArKysr KysrKysrKysrKysrKysrKysrKysrKysrKysrLS0tLS0tLS0tLS0tLS0NCiAyIGZpbGVzIGNoYW5n ZWQsIDQ2IGluc2VydGlvbnMoKyksIDE4IGRlbGV0aW9ucygtKQ0KDQpkaWZmIC11IC0tcmVjdXJz aXZlIC0tbmV3LWZpbGUgLS1zaG93LWMtZnVuY3Rpb24gbGludXgtMi42LjQtMjUtcnBjX2ZpeGVz Mi9mcy9uZnMvcmVhZC5jIGxpbnV4LTIuNi40LTI2LXNob3J0X3J3L2ZzL25mcy9yZWFkLmMNCi0t LSBsaW51eC0yLjYuNC0yNS1ycGNfZml4ZXMyL2ZzL25mcy9yZWFkLmMJMjAwNC0wMy0wNiAwMjoy NTo1MS4wMDAwMDAwMDAgLTA1MDANCisrKyBsaW51eC0yLjYuNC0yNi1zaG9ydF9ydy9mcy9uZnMv cmVhZC5jCTIwMDQtMDMtMDYgMDI6NDY6MjIuMDAwMDAwMDAwIC0wNTAwDQpAQCAtNDIxLDggKzQy MSw2IEBAIHN0YXRpYyB2b2lkIG5mc19yZWFkcGFnZV9yZXN1bHRfcGFydGlhbCgNCiAJCQltZW1j bGVhcl9oaWdocGFnZV9mbHVzaChwYWdlLA0KIAkJCQkJCWRhdGEtPmFyZ3MucGdiYXNlICsgcmVz dWx0LA0KIAkJCQkJCXJlcXVlc3QgLSByZXN1bHQpOw0KLQkJCWlmICghZGF0YS0+cmVzLmVvZikN Ci0JCQkJU2V0UGFnZUVycm9yKHBhZ2UpOw0KIAkJfQ0KIAl9IGVsc2UNCiAJCVNldFBhZ2VFcnJv cihwYWdlKTsNCkBAIC00NTMsOCArNDUxLDYgQEAgc3RhdGljIHZvaWQgbmZzX3JlYWRwYWdlX3Jl c3VsdF9mdWxsKHN0cg0KIAkJCQkJbWVtY2xlYXJfaGlnaHBhZ2VfZmx1c2gocGFnZSwNCiAJCQkJ CQkJcmVxLT53Yl9wZ2Jhc2UgKyBjb3VudCwNCiAJCQkJCQkJcmVxLT53Yl9ieXRlcyAtIGNvdW50 KTsNCi0JCQkJaWYgKCFkYXRhLT5yZXMuZW9mKQ0KLQkJCQkJU2V0UGFnZUVycm9yKHBhZ2UpOw0K IAkJCQljb3VudCA9IDA7DQogCQkJfSBlbHNlDQogCQkJCWNvdW50IC09IFBBR0VfQ0FDSEVfU0la RTsNCkBAIC00NzIsMTEgKzQ2OCwyNiBAQCBzdGF0aWMgdm9pZCBuZnNfcmVhZHBhZ2VfcmVzdWx0 X2Z1bGwoc3RyDQogdm9pZCBuZnNfcmVhZHBhZ2VfcmVzdWx0KHN0cnVjdCBycGNfdGFzayAqdGFz aykNCiB7DQogCXN0cnVjdCBuZnNfcmVhZF9kYXRhICpkYXRhID0gKHN0cnVjdCBuZnNfcmVhZF9k YXRhICopdGFzay0+dGtfY2FsbGRhdGE7DQorCXN0cnVjdCBuZnNfcmVhZGFyZ3MgKmFyZ3AgPSAm ZGF0YS0+YXJnczsNCisJc3RydWN0IG5mc19yZWFkcmVzICpyZXNwID0gJmRhdGEtPnJlczsNCiAJ aW50IHN0YXR1cyA9IHRhc2stPnRrX3N0YXR1czsNCiANCiAJZHByaW50aygiTkZTOiAlNGQgbmZz X3JlYWRwYWdlX3Jlc3VsdCwgKHN0YXR1cyAlZClcbiIsDQogCQl0YXNrLT50a19waWQsIHN0YXR1 cyk7DQogDQorCS8qIElzIHRoaXMgYSBzaG9ydCByZWFkPyAqLw0KKwlpZiAodGFzay0+dGtfc3Rh dHVzID49IDAgJiYgcmVzcC0+Y291bnQgPCBhcmdwLT5jb3VudCAmJiAhcmVzcC0+ZW9mKSB7DQor CQkvKiBIYXMgdGhlIHNlcnZlciBhdCBsZWFzdCBtYWRlIHNvbWUgcHJvZ3Jlc3M/ICovDQorCQlp ZiAocmVzcC0+Y291bnQgIT0gMCkgew0KKwkJCS8qIFllcywgc28gcmV0cnkgdGhlIHJlYWQgYXQg dGhlIGVuZCBvZiB0aGUgZGF0YSAqLw0KKwkJCWFyZ3AtPm9mZnNldCArPSByZXNwLT5jb3VudDsN CisJCQlhcmdwLT5wZ2Jhc2UgKz0gcmVzcC0+Y291bnQ7DQorCQkJYXJncC0+Y291bnQgLT0gcmVz cC0+Y291bnQ7DQorCQkJcnBjX3Jlc3RhcnRfY2FsbCh0YXNrKTsNCisJCQlyZXR1cm47DQorCQl9 DQorCQl0YXNrLT50a19zdGF0dXMgPSAtRUlPOw0KKwl9DQogCU5GU19GTEFHUyhkYXRhLT5pbm9k ZSkgfD0gTkZTX0lOT19JTlZBTElEX0FUSU1FOw0KIAlkYXRhLT5jb21wbGV0ZShkYXRhLCBzdGF0 dXMpOw0KIH0NCmRpZmYgLXUgLS1yZWN1cnNpdmUgLS1uZXctZmlsZSAtLXNob3ctYy1mdW5jdGlv biBsaW51eC0yLjYuNC0yNS1ycGNfZml4ZXMyL2ZzL25mcy93cml0ZS5jIGxpbnV4LTIuNi40LTI2 LXNob3J0X3J3L2ZzL25mcy93cml0ZS5jDQotLS0gbGludXgtMi42LjQtMjUtcnBjX2ZpeGVzMi9m cy9uZnMvd3JpdGUuYwkyMDA0LTAzLTA2IDAyOjI1OjUxLjAwMDAwMDAwMCAtMDUwMA0KKysrIGxp bnV4LTIuNi40LTI2LXNob3J0X3J3L2ZzL25mcy93cml0ZS5jCTIwMDQtMDMtMDYgMDI6NDg6Mjgu MDAwMDAwMDAwIC0wNTAwDQpAQCAtMTE0MCwyMCArMTE0MCw4IEBAIHZvaWQgbmZzX3dyaXRlYmFj a19kb25lKHN0cnVjdCBycGNfdGFzayANCiAJZHByaW50aygiTkZTOiAlNGQgbmZzX3dyaXRlYmFj a19kb25lIChzdGF0dXMgJWQpXG4iLA0KIAkJdGFzay0+dGtfcGlkLCB0YXNrLT50a19zdGF0dXMp Ow0KIA0KLQkvKiBXZSBjYW4ndCBoYW5kbGUgdGhhdCB5ZXQgYnV0IHdlIGNoZWNrIGZvciBpdCBu ZXZlcnRoZWxlc3MgKi8NCi0JaWYgKHJlc3AtPmNvdW50IDwgYXJncC0+Y291bnQgJiYgdGFzay0+ dGtfc3RhdHVzID49IDApIHsNCi0JCXN0YXRpYyB1bnNpZ25lZCBsb25nICAgIGNvbXBsYWluOw0K LQkJaWYgKHRpbWVfYmVmb3JlKGNvbXBsYWluLCBqaWZmaWVzKSkgew0KLQkJCXByaW50ayhLRVJO X1dBUk5JTkcNCi0JCQkgICAgICAgIk5GUzogU2VydmVyIHdyb3RlIGxlc3MgdGhhbiByZXF1ZXN0 ZWQuXG4iKTsNCi0JCQljb21wbGFpbiA9IGppZmZpZXMgKyAzMDAgKiBIWjsNCi0JCX0NCi0JCS8q IENhbid0IGRvIGFueXRoaW5nIGFib3V0IGl0IHJpZ2h0IG5vdyBleGNlcHQgdGhyb3cNCi0JCSAq IGFuIGVycm9yLiAqLw0KLQkJdGFzay0+dGtfc3RhdHVzID0gLUVJTzsNCi0JfQ0KICNpZiBkZWZp bmVkKENPTkZJR19ORlNfVjMpIHx8IGRlZmluZWQoQ09ORklHX05GU19WNCkNCi0JaWYgKGRhdGEt PnZlcmYuY29tbWl0dGVkIDwgYXJncC0+c3RhYmxlICYmIHRhc2stPnRrX3N0YXR1cyA+PSAwKSB7 DQorCWlmIChyZXNwLT52ZXJmLT5jb21taXR0ZWQgPCBhcmdwLT5zdGFibGUgJiYgdGFzay0+dGtf c3RhdHVzID49IDApIHsNCiAJCS8qIFdlIHRyaWVkIGEgd3JpdGUgY2FsbCwgYnV0IHRoZSBzZXJ2 ZXIgZGlkIG5vdA0KIAkJICogY29tbWl0IGRhdGEgdG8gc3RhYmxlIHN0b3JhZ2UgZXZlbiB0aG91 Z2ggd2UNCiAJCSAqIHJlcXVlc3RlZCBpdC4NCkBAIC0xMTY4LDExICsxMTU2LDQwIEBAIHZvaWQg bmZzX3dyaXRlYmFja19kb25lKHN0cnVjdCBycGNfdGFzayANCiAJCQlkcHJpbnRrKCJORlM6IGZh dWx0eSBORlMgc2VydmVyICVzOiINCiAJCQkJIiAoY29tbWl0dGVkID0gJWQpICE9IChzdGFibGUg PSAlZClcbiIsDQogCQkJCU5GU19TRVJWRVIoZGF0YS0+aW5vZGUpLT5ob3N0bmFtZSwNCi0JCQkJ ZGF0YS0+dmVyZi5jb21taXR0ZWQsIGFyZ3AtPnN0YWJsZSk7DQorCQkJCXJlc3AtPnZlcmYtPmNv bW1pdHRlZCwgYXJncC0+c3RhYmxlKTsNCiAJCQljb21wbGFpbiA9IGppZmZpZXMgKyAzMDAgKiBI WjsNCiAJCX0NCiAJfQ0KICNlbmRpZg0KKwkvKiBJcyB0aGlzIGEgc2hvcnQgd3JpdGU/ICovDQor CWlmICh0YXNrLT50a19zdGF0dXMgPj0gMCAmJiByZXNwLT5jb3VudCA8IGFyZ3AtPmNvdW50KSB7 DQorCQlzdGF0aWMgdW5zaWduZWQgbG9uZyAgICBjb21wbGFpbjsNCisNCisJCS8qIEhhcyB0aGUg c2VydmVyIGF0IGxlYXN0IG1hZGUgc29tZSBwcm9ncmVzcz8gKi8NCisJCWlmIChyZXNwLT5jb3Vu dCAhPSAwKSB7DQorCQkJLyogV2FzIHRoaXMgYW4gTkZTdjIgd3JpdGUgb3IgYW4gTkZTdjMgc3Rh YmxlIHdyaXRlPyAqLw0KKwkJCWlmIChyZXNwLT52ZXJmLT5jb21taXR0ZWQgIT0gTkZTX1VOU1RB QkxFKSB7DQorCQkJCS8qIFJlc2VuZCBmcm9tIHdoZXJlIHRoZSBzZXJ2ZXIgbGVmdCBvZmYgKi8N CisJCQkJYXJncC0+b2Zmc2V0ICs9IHJlc3AtPmNvdW50Ow0KKwkJCQlhcmdwLT5wZ2Jhc2UgKz0g cmVzcC0+Y291bnQ7DQorCQkJCWFyZ3AtPmNvdW50IC09IHJlc3AtPmNvdW50Ow0KKwkJCX0gZWxz ZSB7DQorCQkJCS8qIFJlc2VuZCBhcyBhIHN0YWJsZSB3cml0ZSBpbiBvcmRlciB0byBhdm9pZA0K KwkJCQkgKiBoZWFkYWNoZXMgaW4gdGhlIGNhc2Ugb2YgYSBzZXJ2ZXIgY3Jhc2guDQorCQkJCSAq Lw0KKwkJCQlhcmdwLT5zdGFibGUgPSBORlNfRklMRV9TWU5DOw0KKwkJCX0NCisJCQlycGNfcmVz dGFydF9jYWxsKHRhc2spOw0KKwkJCXJldHVybjsNCisJCX0NCisJCWlmICh0aW1lX2JlZm9yZShj b21wbGFpbiwgamlmZmllcykpIHsNCisJCQlwcmludGsoS0VSTl9XQVJOSU5HDQorCQkJICAgICAg ICJORlM6IFNlcnZlciB3cm90ZSBsZXNzIHRoYW4gcmVxdWVzdGVkLlxuIik7DQorCQkJY29tcGxh aW4gPSBqaWZmaWVzICsgMzAwICogSFo7DQorCQl9DQorCQkvKiBDYW4ndCBkbyBhbnl0aGluZyBh Ym91dCBpdCBleGNlcHQgdGhyb3cgYW4gZXJyb3IuICovDQorCQl0YXNrLT50a19zdGF0dXMgPSAt RUlPOw0KKwl9DQogDQogCS8qDQogCSAqIFByb2Nlc3MgdGhlIG5mc19wYWdlIGxpc3QNCk== --=-FFtuzYZJrfmt3IifntWE-- --- 25-akpm/fs/nfs/read.c | 19 +++++++++++++++---- 25-akpm/fs/nfs/write.c | 45 +++++++++++++++++++++++++++++++-------------- 2 files changed, 46 insertions(+), 18 deletions(-) diff -puN fs/nfs/read.c~nfs-08-short_rw fs/nfs/read.c --- 25/fs/nfs/read.c~nfs-08-short_rw 2004-03-14 15:13:10.579000832 -0800 +++ 25-akpm/fs/nfs/read.c 2004-03-14 15:13:10.582000376 -0800 @@ -421,8 +421,6 @@ static void nfs_readpage_result_partial( memclear_highpage_flush(page, data->args.pgbase + result, request - result); - if (!data->res.eof) - SetPageError(page); } } else SetPageError(page); @@ -453,8 +451,6 @@ static void nfs_readpage_result_full(str 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; @@ -472,11 +468,26 @@ static void nfs_readpage_result_full(str void nfs_readpage_result(struct rpc_task *task) { struct nfs_read_data *data = (struct nfs_read_data *)task->tk_calldata; + struct nfs_readargs *argp = &data->args; + struct nfs_readres *resp = &data->res; int status = task->tk_status; dprintk("NFS: %4d nfs_readpage_result, (status %d)\n", task->tk_pid, status); + /* Is this a short read? */ + if (task->tk_status >= 0 && resp->count < argp->count && !resp->eof) { + /* Has the server at least made some progress? */ + if (resp->count != 0) { + /* Yes, so retry the read at the end of the data */ + argp->offset += resp->count; + argp->pgbase += resp->count; + argp->count -= resp->count; + rpc_restart_call(task); + return; + } + task->tk_status = -EIO; + } NFS_FLAGS(data->inode) |= NFS_INO_INVALID_ATIME; data->complete(data, status); } diff -puN fs/nfs/write.c~nfs-08-short_rw fs/nfs/write.c --- 25/fs/nfs/write.c~nfs-08-short_rw 2004-03-14 15:13:10.580000680 -0800 +++ 25-akpm/fs/nfs/write.c 2004-03-14 15:13:10.584000072 -0800 @@ -1141,20 +1141,8 @@ void nfs_writeback_done(struct rpc_task dprintk("NFS: %4d nfs_writeback_done (status %d)\n", task->tk_pid, task->tk_status); - /* We can't handle that yet but we check for it nevertheless */ - if (resp->count < argp->count && task->tk_status >= 0) { - static unsigned long complain; - if (time_before(complain, jiffies)) { - printk(KERN_WARNING - "NFS: Server wrote less than requested.\n"); - complain = jiffies + 300 * HZ; - } - /* Can't do anything about it right now except throw - * an error. */ - task->tk_status = -EIO; - } #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) - if (data->verf.committed < argp->stable && task->tk_status >= 0) { + if (resp->verf->committed < argp->stable && task->tk_status >= 0) { /* We tried a write call, but the server did not * commit data to stable storage even though we * requested it. @@ -1169,11 +1157,40 @@ void nfs_writeback_done(struct rpc_task dprintk("NFS: faulty NFS server %s:" " (committed = %d) != (stable = %d)\n", NFS_SERVER(data->inode)->hostname, - data->verf.committed, argp->stable); + resp->verf->committed, argp->stable); complain = jiffies + 300 * HZ; } } #endif + /* Is this a short write? */ + if (task->tk_status >= 0 && resp->count < argp->count) { + static unsigned long complain; + + /* Has the server at least made some progress? */ + if (resp->count != 0) { + /* Was this an NFSv2 write or an NFSv3 stable write? */ + if (resp->verf->committed != NFS_UNSTABLE) { + /* Resend from where the server left off */ + argp->offset += resp->count; + argp->pgbase += resp->count; + argp->count -= resp->count; + } else { + /* Resend as a stable write in order to avoid + * headaches in the case of a server crash. + */ + argp->stable = NFS_FILE_SYNC; + } + rpc_restart_call(task); + return; + } + if (time_before(complain, jiffies)) { + printk(KERN_WARNING + "NFS: Server wrote less than requested.\n"); + complain = jiffies + 300 * HZ; + } + /* Can't do anything about it except throw an error. */ + task->tk_status = -EIO; + } /* * Process the nfs_page list _