2017-07-19 13:58:26

by Mkrtchyan, Tigran

[permalink] [raw]
Subject: SETATTR without stateid

Dear friends,

By running xfstest (generic/013) I have discovered client side misbehavior.
Consider the following test code:

-----

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>


int main(int argc, char **argv)
{

if (argc != 2) {
fprintf(stderr, "Usage: %s <path>\n", argv[0]);
exit(1);
}

int rc = truncate(argv[1], 8192);
if (rc < 0) {
perror("Failed to truncate the file");
exit(4);
}
exit(0);
}


----

The expectation is that client will send a valid open stateid with SETATTR (rfc7530#16.32.4).
However, this is not the case - client just send's a SETATTR with size, but without any open.

BTW, older clients (RHEL6) will fail with EIO, latest kernel, 4.13.0-rc1 goes into an
infinite loop of SETATTR requests.

On the other hand, ftruncate works as expected, e.q. following example:

---
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>


int main(int argc, char **argv)
{

if (argc != 2) {
fprintf(stderr, "Usage: %s <path>\n", argv[0]);
exit(1);
}

int fd = open(argv[1], O_RDWR, 0644);
if (fd < 0) {
perror("Failed to open file");
exit(2);
}

int rc = ftruncate(fd, 8192);
if (rc < 0) {
perror("Failed to truncate the file");
exit(4);
}

close(fd);
exit(0);
}
----
Will provide an open stateid with SETATTR requests as mandated by rfc.

Tigran.


2017-07-19 14:22:46

by Olga Kornievskaia

[permalink] [raw]
Subject: Re: SETATTR without stateid

On Wed, Jul 19, 2017 at 9:58 AM, Mkrtchyan, Tigran
<[email protected]> wrote:
> Dear friends,
>
> By running xfstest (generic/013) I have discovered client side misbehavior.
> Consider the following test code:
>
> -----
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <unistd.h>
> #include <fcntl.h>
>
>
> int main(int argc, char **argv)
> {
>
> if (argc != 2) {
> fprintf(stderr, "Usage: %s <path>\n", argv[0]);
> exit(1);
> }
>
> int rc = truncate(argv[1], 8192);
> if (rc < 0) {
> perror("Failed to truncate the file");
> exit(4);
> }
> exit(0);
> }
>
>
> ----
>
> The expectation is that client will send a valid open stateid with SETATTR (rfc7530#16.32.4).
> However, this is not the case - client just send's a SETATTR with size, but without any open.

SETATTR is allowed to send an all-zero stateid:

RFC7530 9.1.4.3

Anonymous Stateid: When "other" and seqid are both zero, the stateid
is treated as a special anonymous stateid, which can be used in
READ, WRITE, and SETATTR requests to indicate the absence of any
open state associated with the request.

> BTW, older clients (RHEL6) will fail with EIO, latest kernel, 4.13.0-rc1 goes into an
> infinite loop of SETATTR requests.

What does the server replies with in such case? I believe the client
assumes that SETATTR with all zeros will always be allowed and it will
not be checking anything if it gets BAD_STATEID and will automatically
re-try on BAD_STATEID with zero stateid (therefore it would explain
the loop you are seeing).

Older clients (RHEL6) did not have an option of retrying the SETATTR
that got the BAD_STATEID (on a delegation stateid) and retrying with
zero stateid which is allowed by the spec.

> On the other hand, ftruncate works as expected, e.q. following example:
>
> ---
> #include <stdio.h>
> #include <stdlib.h>
> #include <unistd.h>
> #include <fcntl.h>
>
>
> int main(int argc, char **argv)
> {
>
> if (argc != 2) {
> fprintf(stderr, "Usage: %s <path>\n", argv[0]);
> exit(1);
> }
>
> int fd = open(argv[1], O_RDWR, 0644);
> if (fd < 0) {
> perror("Failed to open file");
> exit(2);
> }
>
> int rc = ftruncate(fd, 8192);
> if (rc < 0) {
> perror("Failed to truncate the file");
> exit(4);
> }
>
> close(fd);
> exit(0);
> }
> ----
> Will provide an open stateid with SETATTR requests as mandated by rfc.

Yes that version of the user land "setattr" is on the file descriptor
so there was an opens stateid to be used by the nfs setattr.
"truncate" is on the file name and nfs does not underneath open a file
to satisfy this command.

>
> Tigran.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html

2017-07-19 14:33:32

by Trond Myklebust

[permalink] [raw]
Subject: Re: SETATTR without stateid

T24gV2VkLCAyMDE3LTA3LTE5IGF0IDEwOjIyIC0wNDAwLCBPbGdhIEtvcm5pZXZza2FpYSB3cm90
ZToNCj4gT24gV2VkLCBKdWwgMTksIDIwMTcgYXQgOTo1OCBBTSwgTWtydGNoeWFuLCBUaWdyYW4N
Cj4gPHRpZ3Jhbi5ta3J0Y2h5YW5AZGVzeS5kZT4gd3JvdGU6DQo+ID4gRGVhciBmcmllbmRzLA0K
PiA+IA0KPiA+IEJ5IHJ1bm5pbmcgeGZzdGVzdCAoZ2VuZXJpYy8wMTMpIEkgaGF2ZSBkaXNjb3Zl
cmVkIGNsaWVudCBzaWRlDQo+ID4gbWlzYmVoYXZpb3IuDQo+ID4gQ29uc2lkZXIgdGhlIGZvbGxv
d2luZyB0ZXN0IGNvZGU6DQo+ID4gDQo+ID4gLS0tLS0NCj4gPiANCj4gPiAjaW5jbHVkZSA8c3Rk
aW8uaD4NCj4gPiAjaW5jbHVkZSA8c3RkbGliLmg+DQo+ID4gI2luY2x1ZGUgPHVuaXN0ZC5oPg0K
PiA+ICNpbmNsdWRlIDxmY250bC5oPg0KPiA+IA0KPiA+IA0KPiA+IGludCBtYWluKGludCBhcmdj
LCBjaGFyICoqYXJndikNCj4gPiB7DQo+ID4gDQo+ID4gICBpZiAoYXJnYyAhPSAyKSB7DQo+ID4g
ICAgIGZwcmludGYoc3RkZXJyLCAiVXNhZ2U6ICVzIDxwYXRoPlxuIiwgYXJndlswXSk7DQo+ID4g
ICAgIGV4aXQoMSk7DQo+ID4gICB9DQo+ID4gDQo+ID4gICBpbnQgcmMgPSB0cnVuY2F0ZShhcmd2
WzFdLCA4MTkyKTsNCj4gPiAgIGlmIChyYyA8IDApIHsNCj4gPiAgICAgcGVycm9yKCJGYWlsZWQg
dG8gdHJ1bmNhdGUgdGhlIGZpbGUiKTsNCj4gPiAgICAgZXhpdCg0KTsNCj4gPiAgIH0NCj4gPiAg
IGV4aXQoMCk7DQo+ID4gfQ0KPiA+IA0KPiA+IA0KPiA+IC0tLS0NCj4gPiANCj4gPiBUaGUgZXhw
ZWN0YXRpb24gaXMgdGhhdCBjbGllbnQgd2lsbCBzZW5kIGEgdmFsaWQgb3BlbiBzdGF0ZWlkIHdp
dGgNCj4gPiBTRVRBVFRSIChyZmM3NTMwIzE2LjMyLjQpLg0KPiA+IEhvd2V2ZXIsIHRoaXMgaXMg
bm90IHRoZSBjYXNlIC0gY2xpZW50IGp1c3Qgc2VuZCdzIGEgU0VUQVRUUiB3aXRoDQo+ID4gc2l6
ZSwgYnV0IHdpdGhvdXQgYW55IG9wZW4uDQo+IA0KPiBTRVRBVFRSIGlzIGFsbG93ZWQgdG8gc2Vu
ZCBhbiBhbGwtemVybyBzdGF0ZWlkOg0KPiANCj4gUkZDNzUzMCA5LjEuNC4zDQo+IA0KPiBBbm9u
eW1vdXMgU3RhdGVpZDogIFdoZW4gIm90aGVyIiBhbmQgc2VxaWQgYXJlIGJvdGggemVybywgdGhl
IHN0YXRlaWQNCj4gICAgICAgaXMgdHJlYXRlZCBhcyBhIHNwZWNpYWwgYW5vbnltb3VzIHN0YXRl
aWQsIHdoaWNoIGNhbiBiZSB1c2VkIGluDQo+ICAgICAgIFJFQUQsIFdSSVRFLCBhbmQgU0VUQVRU
UiByZXF1ZXN0cyB0byBpbmRpY2F0ZSB0aGUgYWJzZW5jZSBvZg0KPiBhbnkNCj4gICAgICAgb3Bl
biBzdGF0ZSBhc3NvY2lhdGVkIHdpdGggdGhlIHJlcXVlc3QuDQoNCkFncmVlZC4gQXMgT2xnYSBz
YXlzLCB0aGVyZSBpcyBubyBzcGVjIHJlcXVpcmVtZW50IHRoYXQgdGhlIGNsaWVudCBvcGVuDQp0
aGUgZmlsZSBpbiBvcmRlciB0byBzZXJ2aWNlIGEgdHJ1bmNhdGUoKSBjYWxsLCBzbyB0aGlzIGJl
aGF2aW91ciBpcyBieQ0KZGVzaWduLg0KDQpDaGVlcnMNCiAgVHJvbmQNCi0tIA0KVHJvbmQgTXlr
bGVidXN0DQpMaW51eCBORlMgY2xpZW50IG1haW50YWluZXIsIFByaW1hcnlEYXRhDQp0cm9uZC5t
eWtsZWJ1c3RAcHJpbWFyeWRhdGEuY29tDQo=


2017-07-19 15:37:11

by Mkrtchyan, Tigran

[permalink] [raw]
Subject: Re: SETATTR without stateid



Ok, Thanks for clarification. I probably misread some sentences like:

A valid stateid SHOULD always be specified. When the file size
attribute is not set, the special anonymous stateid MAY be passed.

anyway, it's I have to handle it on the server as RHEL6 clients won't get
any new updates.

Tigran.
----- Original Message -----
> From: "Trond Myklebust" <[email protected]>
> To: "Tigran Mkrtchyan" <[email protected]>, "Olga Kornievskaia" <a=
[email protected]>
> Cc: "linux-nfs" <[email protected]>
> Sent: Wednesday, July 19, 2017 4:33:27 PM
> Subject: Re: SETATTR without stateid

> On Wed, 2017-07-19 at 10:22 -0400, Olga Kornievskaia wrote:
>> On Wed, Jul 19, 2017 at 9:58 AM, Mkrtchyan, Tigran
>> <[email protected]> wrote:
>> > Dear friends,
>> >=20
>> > By running xfstest (generic/013) I have discovered client side
>> > misbehavior.
>> > Consider the following test code:
>> >=20
>> > -----
>> >=20
>> > #include <stdio.h>
>> > #include <stdlib.h>
>> > #include <unistd.h>
>> > #include <fcntl.h>
>> >=20
>> >=20
>> > int main(int argc, char **argv)
>> > {
>> >=20
>> > if (argc !=3D 2) {
>> > fprintf(stderr, "Usage: %s <path>\n", argv[0]);
>> > exit(1);
>> > }
>> >=20
>> > int rc =3D truncate(argv[1], 8192);
>> > if (rc < 0) {
>> > perror("Failed to truncate the file");
>> > exit(4);
>> > }
>> > exit(0);
>> > }
>> >=20
>> >=20
>> > ----
>> >=20
>> > The expectation is that client will send a valid open stateid with
>> > SETATTR (rfc7530#16.32.4).
>> > However, this is not the case - client just send's a SETATTR with
>> > size, but without any open.
>>=20
>> SETATTR is allowed to send an all-zero stateid:
>>=20
>> RFC7530 9.1.4.3
>>=20
>> Anonymous Stateid: When "other" and seqid are both zero, the stateid
>> is treated as a special anonymous stateid, which can be used in
>> READ, WRITE, and SETATTR requests to indicate the absence of
>> any
>> open state associated with the request.
>=20
> Agreed. As Olga says, there is no spec requirement that the client open
> the file in order to service a truncate() call, so this behaviour is by
> design.
>=20
> Cheers
> Trond
> --
> Trond Myklebust
> Linux NFS client maintainer, PrimaryData
> [email protected]
> N=EF=BF=BD=EF=BF=BD=EF=BF=BD=EF=BF=BD=EF=BF=BDr=EF=BF=BD=EF=BF=BDy=EF=BF=
=BD=EF=BF=BD=EF=BF=BDb=EF=BF=BDX=EF=BF=BD=EF=BF=BD=C7=A7v=EF=BF=BD^=EF=BF=
=BD)=DE=BA{.n=EF=BF=BD+=EF=BF=BD=EF=BF=BD=EF=BF=BD=EF=BF=BD{=EF=BF=BD=EF=BF=
=BD=EF=BF=BD"=EF=BF=BD=EF=BF=BD^n=EF=BF=BDr=EF=BF=BD=EF=BF=BD=EF=BF=BDz=EF=
=BF=BD=EF=BF=BD=EF=BF=BDh=EF=BF=BD=EF=BF=BD=EF=BF=BD=EF=BF=BD&=EF=BF=BD=EF=
=BF=BD=EF=BF=BDG=EF=BF=BD=EF=BF=BD=EF=BF=BDh=EF=BF=BD(=EF=BF=BD=E9=9A=8E=EF=
=BF=BD=DD=A2j"=EF=BF=BD=EF=BF=BD=EF=BF=BDm=EF=BF=BD=EF=BF=BD=EF=BF=BD=EF=BF=
=BD=EF=BF=BDz=EF=BF=BD=DE=96=EF=BF=BD=EF=BF=BD=EF=BF=BDf=EF=BF=BD=EF=BF=BD=
=EF=BF=BDh=EF=BF=BD=EF=BF=BD=EF=BF=BD~=EF=BF=BDm=EF=BF=BD