2022-01-28 11:24:07

by Chuck Lever

[permalink] [raw]
Subject: [PATCH] nfsv4.0/setattr: Check behavior of setting a large file size

Many POSIX systems internally use a signed file size. The NFS
server has to correctly handle the conversion from a u64 size
to the internal size value.

Signed-off-by: Chuck Lever <[email protected]>
---
nfs4.0/servertests/st_setattr.py | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)

Just something to consider... "It's my first ray gun" so I'm sure
I got something wrong here.

diff --git a/nfs4.0/servertests/st_setattr.py b/nfs4.0/servertests/st_setattr.py
index c3ecee3fbcfb..5d51054c29b4 100644
--- a/nfs4.0/servertests/st_setattr.py
+++ b/nfs4.0/servertests/st_setattr.py
@@ -562,6 +562,25 @@ def testUnsupportedSocket(t, env):
check(res)
_try_unsupported(t, env, path)

+def testMaxSizeFile(t, env):
+ """SETATTR(U64_MAX) of a file should return NFS4_OK or NFS4ERR_FBIG
+
+ FLAGS: setattr all
+ DEPEND: INIT
+ CODE: SATT12x
+ """
+ maxsize = 0xffffffffffffffff
+ c = env.c1
+ fh, stateid = c.create_confirm(t.word(), deny=OPEN4_SHARE_DENY_NONE)
+ dict = {FATTR4_SIZE: maxsize}
+ ops = c.use_obj(fh) + [c.setattr(dict, stateid)]
+ res = c.compound(ops)
+ check(res, [NFS4_OK, NFS4ERR_FBIG], "SETATTR(U64_MAX) of a file")
+ newsize = c.do_getattr(FATTR4_SIZE, fh)
+ if newsize != maxsize:
+ check(res, [NFS4ERR_INVAL, NFS4ERR_FBIG],
+ "File size is %i; SETATTR" % newsize)
+
def testSizeDir(t, env):
"""SETATTR(_SIZE) of a directory should return NFS4ERR_ISDIR or NFS4ERR_BAD_STATEID




2022-01-28 20:39:19

by J. Bruce Fields

[permalink] [raw]
Subject: Re: [PATCH] nfsv4.0/setattr: Check behavior of setting a large file size

On Thu, Jan 27, 2022 at 12:19:24PM -0500, Chuck Lever wrote:
> Many POSIX systems internally use a signed file size. The NFS
> server has to correctly handle the conversion from a u64 size
> to the internal size value.
>
> Signed-off-by: Chuck Lever <[email protected]>
> ---
> nfs4.0/servertests/st_setattr.py | 19 +++++++++++++++++++
> 1 file changed, 19 insertions(+)
>
> Just something to consider... "It's my first ray gun" so I'm sure
> I got something wrong here.

Looks fine by me; applied.

--b.

>
> diff --git a/nfs4.0/servertests/st_setattr.py b/nfs4.0/servertests/st_setattr.py
> index c3ecee3fbcfb..5d51054c29b4 100644
> --- a/nfs4.0/servertests/st_setattr.py
> +++ b/nfs4.0/servertests/st_setattr.py
> @@ -562,6 +562,25 @@ def testUnsupportedSocket(t, env):
> check(res)
> _try_unsupported(t, env, path)
>
> +def testMaxSizeFile(t, env):
> + """SETATTR(U64_MAX) of a file should return NFS4_OK or NFS4ERR_FBIG
> +
> + FLAGS: setattr all
> + DEPEND: INIT
> + CODE: SATT12x
> + """
> + maxsize = 0xffffffffffffffff
> + c = env.c1
> + fh, stateid = c.create_confirm(t.word(), deny=OPEN4_SHARE_DENY_NONE)
> + dict = {FATTR4_SIZE: maxsize}
> + ops = c.use_obj(fh) + [c.setattr(dict, stateid)]
> + res = c.compound(ops)
> + check(res, [NFS4_OK, NFS4ERR_FBIG], "SETATTR(U64_MAX) of a file")
> + newsize = c.do_getattr(FATTR4_SIZE, fh)
> + if newsize != maxsize:
> + check(res, [NFS4ERR_INVAL, NFS4ERR_FBIG],
> + "File size is %i; SETATTR" % newsize)
> +
> def testSizeDir(t, env):
> """SETATTR(_SIZE) of a directory should return NFS4ERR_ISDIR or NFS4ERR_BAD_STATEID
>
>