* [PATCH] Add some tests for unsupported fattr4 attributes
@ 2025-09-29 20:16 Chuck Lever
2025-09-29 21:14 ` Calum Mackay
2025-09-30 11:34 ` Jeff Layton
0 siblings, 2 replies; 5+ messages in thread
From: Chuck Lever @ 2025-09-29 20:16 UTC (permalink / raw)
To: Calum Mackay; +Cc: linux-nfs, Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
Linux NFSD does not implement a handful of these NFSv4.0 fattr4
attributes. Ensure that NFSD's fattr4 result encoder is correctly
clearing the result mask and returning NFS4_OK.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
nfs4.0/servertests/st_getattr.py | 149 +++++++++++++++++++++++++++++++
1 file changed, 149 insertions(+)
diff --git a/nfs4.0/servertests/st_getattr.py b/nfs4.0/servertests/st_getattr.py
index 1c47ebf60571..d423aa1df46d 100644
--- a/nfs4.0/servertests/st_getattr.py
+++ b/nfs4.0/servertests/st_getattr.py
@@ -521,6 +521,155 @@ def testOwnerName(t, env):
t.fail_support("owner not a supported attribute")
# print(res.resarray[-1].obj_attributes)
+def testArchive(t, env):
+ """GETATTR on "archive" attribute
+
+ FLAGS: getattr all
+ DEPEND: LOOKFILE
+ CODE: GATT11a
+ """
+ c = env.c1
+ ops = c.use_obj(env.opts.usefile)
+ ops += [c.getattr([FATTR4_ARCHIVE])]
+ res = c.compound(ops)
+ check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(archive)")
+ if res.status == NFS4ERR_ATTRNOTSUPP:
+ t.fail_support("archive not a supported attribute")
+
+def testHidden(t, env):
+ """GETATTR on "hidden" attribute
+
+ FLAGS: getattr all
+ DEPEND: LOOKFILE
+ CODE: GATT11b
+ """
+ c = env.c1
+ ops = c.use_obj(env.opts.usefile)
+ ops += [c.getattr([FATTR4_HIDDEN])]
+ res = c.compound(ops)
+ check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(hidden)")
+ if res.status == NFS4ERR_ATTRNOTSUPP:
+ t.fail_support("hidden not a supported attribute")
+
+def testMimetype(t, env):
+ """GETATTR on "mimetype" attribute
+
+ FLAGS: getattr all
+ DEPEND: LOOKFILE
+ CODE: GATT11c
+ """
+ c = env.c1
+ ops = c.use_obj(env.opts.usefile)
+ ops += [c.getattr([FATTR4_MIMETYPE])]
+ res = c.compound(ops)
+ check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(mimetype)")
+ if res.status == NFS4ERR_ATTRNOTSUPP:
+ t.fail_support("mimetype not a supported attribute")
+
+def testQuotaAvailHard(t, env):
+ """GETATTR on "quota avail hard" attribute
+
+ FLAGS: getattr all
+ DEPEND: LOOKFILE
+ CODE: GATT11d
+ """
+ c = env.c1
+ ops = c.use_obj(env.opts.usefile)
+ ops += [c.getattr([FATTR4_QUOTA_AVAIL_HARD])]
+ res = c.compound(ops)
+ check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(quota_avail_hard)")
+ if res.status == NFS4ERR_ATTRNOTSUPP:
+ t.fail_support("quota_avail_hard not a supported attribute")
+
+def testQuotaAvailSoft(t, env):
+ """GETATTR on "quota avail soft" attribute
+
+ FLAGS: getattr all
+ DEPEND: LOOKFILE
+ CODE: GATT11e
+ """
+ c = env.c1
+ ops = c.use_obj(env.opts.usefile)
+ ops += [c.getattr([FATTR4_QUOTA_AVAIL_SOFT])]
+ res = c.compound(ops)
+ check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(quota_avail_soft)")
+ if res.status == NFS4ERR_ATTRNOTSUPP:
+ t.fail_support("quota_avail_soft not a supported attribute")
+
+def testQuotaUsed(t, env):
+ """GETATTR on "quota used" attribute
+
+ FLAGS: getattr all
+ DEPEND: LOOKFILE
+ CODE: GATT11f
+ """
+ c = env.c1
+ ops = c.use_obj(env.opts.usefile)
+ ops += [c.getattr([FATTR4_QUOTA_USED])]
+ res = c.compound(ops)
+ check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(quota_used)")
+ if res.status == NFS4ERR_ATTRNOTSUPP:
+ t.fail_support("quota_used not a supported attribute")
+
+def testSystem(t, env):
+ """GETATTR on "system" attribute
+
+ FLAGS: getattr all
+ DEPEND: LOOKFILE
+ CODE: GATT11g
+ """
+ c = env.c1
+ ops = c.use_obj(env.opts.usefile)
+ ops += [c.getattr([FATTR4_SYSTEM])]
+ res = c.compound(ops)
+ check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(system)")
+ if res.status == NFS4ERR_ATTRNOTSUPP:
+ t.fail_support("system not a supported attribute")
+
+def testTimeBackup(t, env):
+ """GETATTR on "time backup" attribute
+
+ FLAGS: getattr all
+ DEPEND: LOOKFILE
+ CODE: GATT11h
+ """
+ c = env.c1
+ ops = c.use_obj(env.opts.usefile)
+ ops += [c.getattr([FATTR4_TIME_BACKUP])]
+ res = c.compound(ops)
+ check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(time_backup)")
+ if res.status == NFS4ERR_ATTRNOTSUPP:
+ t.fail_support("time_backup not a supported attribute")
+
+def testTimeAccessSet(t, env):
+ """GETATTR on "time access set" attribute (write-only)
+
+ FLAGS: getattr all
+ DEPEND: LOOKFILE
+ CODE: GATT11i
+ """
+ c = env.c1
+ ops = c.use_obj(env.opts.usefile)
+ ops += [c.getattr([FATTR4_TIME_ACCESS_SET])]
+ res = c.compound(ops)
+ check(res, [NFS4ERR_INVAL, NFS4ERR_ATTRNOTSUPP], "GETATTR(time_access_set)")
+ if res.status == NFS4ERR_ATTRNOTSUPP:
+ t.fail_support("time_access_set not a supported attribute")
+
+def testTimeModifySet(t, env):
+ """GETATTR on "time modify set" attribute (write-only)
+
+ FLAGS: getattr all
+ DEPEND: LOOKFILE
+ CODE: GATT11j
+ """
+ c = env.c1
+ ops = c.use_obj(env.opts.usefile)
+ ops += [c.getattr([FATTR4_TIME_MODIFY_SET])]
+ res = c.compound(ops)
+ check(res, [NFS4ERR_INVAL, NFS4ERR_ATTRNOTSUPP], "GETATTR(time_modify_set)")
+ if res.status == NFS4ERR_ATTRNOTSUPP:
+ t.fail_support("time_modify_set not a supported attribute")
####################################################
--
2.51.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] Add some tests for unsupported fattr4 attributes
2025-09-29 20:16 [PATCH] Add some tests for unsupported fattr4 attributes Chuck Lever
@ 2025-09-29 21:14 ` Calum Mackay
2025-09-29 21:16 ` Chuck Lever
2025-09-30 11:34 ` Jeff Layton
1 sibling, 1 reply; 5+ messages in thread
From: Calum Mackay @ 2025-09-29 21:14 UTC (permalink / raw)
To: Chuck Lever; +Cc: Calum Mackay, linux-nfs, Chuck Lever
thanks Chuck,
I'm still catching up with pynfs patches; I'll get this (and the others
queued up) in asap.
cheers,
c.
On 29/09/2025 9:16 pm, Chuck Lever wrote:
> From: Chuck Lever <chuck.lever@oracle.com>
>
> Linux NFSD does not implement a handful of these NFSv4.0 fattr4
> attributes. Ensure that NFSD's fattr4 result encoder is correctly
> clearing the result mask and returning NFS4_OK.
>
> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
> ---
> nfs4.0/servertests/st_getattr.py | 149 +++++++++++++++++++++++++++++++
> 1 file changed, 149 insertions(+)
>
> diff --git a/nfs4.0/servertests/st_getattr.py b/nfs4.0/servertests/st_getattr.py
> index 1c47ebf60571..d423aa1df46d 100644
> --- a/nfs4.0/servertests/st_getattr.py
> +++ b/nfs4.0/servertests/st_getattr.py
> @@ -521,6 +521,155 @@ def testOwnerName(t, env):
> t.fail_support("owner not a supported attribute")
> # print(res.resarray[-1].obj_attributes)
>
> +def testArchive(t, env):
> + """GETATTR on "archive" attribute
> +
> + FLAGS: getattr all
> + DEPEND: LOOKFILE
> + CODE: GATT11a
> + """
> + c = env.c1
> + ops = c.use_obj(env.opts.usefile)
> + ops += [c.getattr([FATTR4_ARCHIVE])]
> + res = c.compound(ops)
> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(archive)")
> + if res.status == NFS4ERR_ATTRNOTSUPP:
> + t.fail_support("archive not a supported attribute")
> +
> +def testHidden(t, env):
> + """GETATTR on "hidden" attribute
> +
> + FLAGS: getattr all
> + DEPEND: LOOKFILE
> + CODE: GATT11b
> + """
> + c = env.c1
> + ops = c.use_obj(env.opts.usefile)
> + ops += [c.getattr([FATTR4_HIDDEN])]
> + res = c.compound(ops)
> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(hidden)")
> + if res.status == NFS4ERR_ATTRNOTSUPP:
> + t.fail_support("hidden not a supported attribute")
> +
> +def testMimetype(t, env):
> + """GETATTR on "mimetype" attribute
> +
> + FLAGS: getattr all
> + DEPEND: LOOKFILE
> + CODE: GATT11c
> + """
> + c = env.c1
> + ops = c.use_obj(env.opts.usefile)
> + ops += [c.getattr([FATTR4_MIMETYPE])]
> + res = c.compound(ops)
> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(mimetype)")
> + if res.status == NFS4ERR_ATTRNOTSUPP:
> + t.fail_support("mimetype not a supported attribute")
> +
> +def testQuotaAvailHard(t, env):
> + """GETATTR on "quota avail hard" attribute
> +
> + FLAGS: getattr all
> + DEPEND: LOOKFILE
> + CODE: GATT11d
> + """
> + c = env.c1
> + ops = c.use_obj(env.opts.usefile)
> + ops += [c.getattr([FATTR4_QUOTA_AVAIL_HARD])]
> + res = c.compound(ops)
> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(quota_avail_hard)")
> + if res.status == NFS4ERR_ATTRNOTSUPP:
> + t.fail_support("quota_avail_hard not a supported attribute")
> +
> +def testQuotaAvailSoft(t, env):
> + """GETATTR on "quota avail soft" attribute
> +
> + FLAGS: getattr all
> + DEPEND: LOOKFILE
> + CODE: GATT11e
> + """
> + c = env.c1
> + ops = c.use_obj(env.opts.usefile)
> + ops += [c.getattr([FATTR4_QUOTA_AVAIL_SOFT])]
> + res = c.compound(ops)
> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(quota_avail_soft)")
> + if res.status == NFS4ERR_ATTRNOTSUPP:
> + t.fail_support("quota_avail_soft not a supported attribute")
> +
> +def testQuotaUsed(t, env):
> + """GETATTR on "quota used" attribute
> +
> + FLAGS: getattr all
> + DEPEND: LOOKFILE
> + CODE: GATT11f
> + """
> + c = env.c1
> + ops = c.use_obj(env.opts.usefile)
> + ops += [c.getattr([FATTR4_QUOTA_USED])]
> + res = c.compound(ops)
> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(quota_used)")
> + if res.status == NFS4ERR_ATTRNOTSUPP:
> + t.fail_support("quota_used not a supported attribute")
> +
> +def testSystem(t, env):
> + """GETATTR on "system" attribute
> +
> + FLAGS: getattr all
> + DEPEND: LOOKFILE
> + CODE: GATT11g
> + """
> + c = env.c1
> + ops = c.use_obj(env.opts.usefile)
> + ops += [c.getattr([FATTR4_SYSTEM])]
> + res = c.compound(ops)
> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(system)")
> + if res.status == NFS4ERR_ATTRNOTSUPP:
> + t.fail_support("system not a supported attribute")
> +
> +def testTimeBackup(t, env):
> + """GETATTR on "time backup" attribute
> +
> + FLAGS: getattr all
> + DEPEND: LOOKFILE
> + CODE: GATT11h
> + """
> + c = env.c1
> + ops = c.use_obj(env.opts.usefile)
> + ops += [c.getattr([FATTR4_TIME_BACKUP])]
> + res = c.compound(ops)
> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(time_backup)")
> + if res.status == NFS4ERR_ATTRNOTSUPP:
> + t.fail_support("time_backup not a supported attribute")
> +
> +def testTimeAccessSet(t, env):
> + """GETATTR on "time access set" attribute (write-only)
> +
> + FLAGS: getattr all
> + DEPEND: LOOKFILE
> + CODE: GATT11i
> + """
> + c = env.c1
> + ops = c.use_obj(env.opts.usefile)
> + ops += [c.getattr([FATTR4_TIME_ACCESS_SET])]
> + res = c.compound(ops)
> + check(res, [NFS4ERR_INVAL, NFS4ERR_ATTRNOTSUPP], "GETATTR(time_access_set)")
> + if res.status == NFS4ERR_ATTRNOTSUPP:
> + t.fail_support("time_access_set not a supported attribute")
> +
> +def testTimeModifySet(t, env):
> + """GETATTR on "time modify set" attribute (write-only)
> +
> + FLAGS: getattr all
> + DEPEND: LOOKFILE
> + CODE: GATT11j
> + """
> + c = env.c1
> + ops = c.use_obj(env.opts.usefile)
> + ops += [c.getattr([FATTR4_TIME_MODIFY_SET])]
> + res = c.compound(ops)
> + check(res, [NFS4ERR_INVAL, NFS4ERR_ATTRNOTSUPP], "GETATTR(time_modify_set)")
> + if res.status == NFS4ERR_ATTRNOTSUPP:
> + t.fail_support("time_modify_set not a supported attribute")
>
> ####################################################
>
--
Calum Mackay
Linux Kernel Engineering
Oracle Linux and Virtualisation
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] Add some tests for unsupported fattr4 attributes
2025-09-29 21:14 ` Calum Mackay
@ 2025-09-29 21:16 ` Chuck Lever
2025-09-29 22:10 ` Calum Mackay
0 siblings, 1 reply; 5+ messages in thread
From: Chuck Lever @ 2025-09-29 21:16 UTC (permalink / raw)
To: Calum Mackay; +Cc: linux-nfs, Chuck Lever
On 9/29/25 2:14 PM, Calum Mackay wrote:
> thanks Chuck,
>
> I'm still catching up with pynfs patches; I'll get this (and the others
> queued up) in asap.
My patch deserves a smell test first, of course. I'm not at all sure
this is reasonable or proper Python.
> cheers,
> c.
>
>
> On 29/09/2025 9:16 pm, Chuck Lever wrote:
>> From: Chuck Lever <chuck.lever@oracle.com>
>>
>> Linux NFSD does not implement a handful of these NFSv4.0 fattr4
>> attributes. Ensure that NFSD's fattr4 result encoder is correctly
>> clearing the result mask and returning NFS4_OK.
>>
>> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
>> ---
>> nfs4.0/servertests/st_getattr.py | 149 +++++++++++++++++++++++++++++++
>> 1 file changed, 149 insertions(+)
>>
>> diff --git a/nfs4.0/servertests/st_getattr.py b/nfs4.0/servertests/
>> st_getattr.py
>> index 1c47ebf60571..d423aa1df46d 100644
>> --- a/nfs4.0/servertests/st_getattr.py
>> +++ b/nfs4.0/servertests/st_getattr.py
>> @@ -521,6 +521,155 @@ def testOwnerName(t, env):
>> t.fail_support("owner not a supported attribute")
>> # print(res.resarray[-1].obj_attributes)
>> +def testArchive(t, env):
>> + """GETATTR on "archive" attribute
>> +
>> + FLAGS: getattr all
>> + DEPEND: LOOKFILE
>> + CODE: GATT11a
>> + """
>> + c = env.c1
>> + ops = c.use_obj(env.opts.usefile)
>> + ops += [c.getattr([FATTR4_ARCHIVE])]
>> + res = c.compound(ops)
>> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(archive)")
>> + if res.status == NFS4ERR_ATTRNOTSUPP:
>> + t.fail_support("archive not a supported attribute")
>> +
>> +def testHidden(t, env):
>> + """GETATTR on "hidden" attribute
>> +
>> + FLAGS: getattr all
>> + DEPEND: LOOKFILE
>> + CODE: GATT11b
>> + """
>> + c = env.c1
>> + ops = c.use_obj(env.opts.usefile)
>> + ops += [c.getattr([FATTR4_HIDDEN])]
>> + res = c.compound(ops)
>> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(hidden)")
>> + if res.status == NFS4ERR_ATTRNOTSUPP:
>> + t.fail_support("hidden not a supported attribute")
>> +
>> +def testMimetype(t, env):
>> + """GETATTR on "mimetype" attribute
>> +
>> + FLAGS: getattr all
>> + DEPEND: LOOKFILE
>> + CODE: GATT11c
>> + """
>> + c = env.c1
>> + ops = c.use_obj(env.opts.usefile)
>> + ops += [c.getattr([FATTR4_MIMETYPE])]
>> + res = c.compound(ops)
>> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(mimetype)")
>> + if res.status == NFS4ERR_ATTRNOTSUPP:
>> + t.fail_support("mimetype not a supported attribute")
>> +
>> +def testQuotaAvailHard(t, env):
>> + """GETATTR on "quota avail hard" attribute
>> +
>> + FLAGS: getattr all
>> + DEPEND: LOOKFILE
>> + CODE: GATT11d
>> + """
>> + c = env.c1
>> + ops = c.use_obj(env.opts.usefile)
>> + ops += [c.getattr([FATTR4_QUOTA_AVAIL_HARD])]
>> + res = c.compound(ops)
>> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP],
>> "GETATTR(quota_avail_hard)")
>> + if res.status == NFS4ERR_ATTRNOTSUPP:
>> + t.fail_support("quota_avail_hard not a supported attribute")
>> +
>> +def testQuotaAvailSoft(t, env):
>> + """GETATTR on "quota avail soft" attribute
>> +
>> + FLAGS: getattr all
>> + DEPEND: LOOKFILE
>> + CODE: GATT11e
>> + """
>> + c = env.c1
>> + ops = c.use_obj(env.opts.usefile)
>> + ops += [c.getattr([FATTR4_QUOTA_AVAIL_SOFT])]
>> + res = c.compound(ops)
>> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP],
>> "GETATTR(quota_avail_soft)")
>> + if res.status == NFS4ERR_ATTRNOTSUPP:
>> + t.fail_support("quota_avail_soft not a supported attribute")
>> +
>> +def testQuotaUsed(t, env):
>> + """GETATTR on "quota used" attribute
>> +
>> + FLAGS: getattr all
>> + DEPEND: LOOKFILE
>> + CODE: GATT11f
>> + """
>> + c = env.c1
>> + ops = c.use_obj(env.opts.usefile)
>> + ops += [c.getattr([FATTR4_QUOTA_USED])]
>> + res = c.compound(ops)
>> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(quota_used)")
>> + if res.status == NFS4ERR_ATTRNOTSUPP:
>> + t.fail_support("quota_used not a supported attribute")
>> +
>> +def testSystem(t, env):
>> + """GETATTR on "system" attribute
>> +
>> + FLAGS: getattr all
>> + DEPEND: LOOKFILE
>> + CODE: GATT11g
>> + """
>> + c = env.c1
>> + ops = c.use_obj(env.opts.usefile)
>> + ops += [c.getattr([FATTR4_SYSTEM])]
>> + res = c.compound(ops)
>> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(system)")
>> + if res.status == NFS4ERR_ATTRNOTSUPP:
>> + t.fail_support("system not a supported attribute")
>> +
>> +def testTimeBackup(t, env):
>> + """GETATTR on "time backup" attribute
>> +
>> + FLAGS: getattr all
>> + DEPEND: LOOKFILE
>> + CODE: GATT11h
>> + """
>> + c = env.c1
>> + ops = c.use_obj(env.opts.usefile)
>> + ops += [c.getattr([FATTR4_TIME_BACKUP])]
>> + res = c.compound(ops)
>> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(time_backup)")
>> + if res.status == NFS4ERR_ATTRNOTSUPP:
>> + t.fail_support("time_backup not a supported attribute")
>> +
>> +def testTimeAccessSet(t, env):
>> + """GETATTR on "time access set" attribute (write-only)
>> +
>> + FLAGS: getattr all
>> + DEPEND: LOOKFILE
>> + CODE: GATT11i
>> + """
>> + c = env.c1
>> + ops = c.use_obj(env.opts.usefile)
>> + ops += [c.getattr([FATTR4_TIME_ACCESS_SET])]
>> + res = c.compound(ops)
>> + check(res, [NFS4ERR_INVAL, NFS4ERR_ATTRNOTSUPP],
>> "GETATTR(time_access_set)")
>> + if res.status == NFS4ERR_ATTRNOTSUPP:
>> + t.fail_support("time_access_set not a supported attribute")
>> +
>> +def testTimeModifySet(t, env):
>> + """GETATTR on "time modify set" attribute (write-only)
>> +
>> + FLAGS: getattr all
>> + DEPEND: LOOKFILE
>> + CODE: GATT11j
>> + """
>> + c = env.c1
>> + ops = c.use_obj(env.opts.usefile)
>> + ops += [c.getattr([FATTR4_TIME_MODIFY_SET])]
>> + res = c.compound(ops)
>> + check(res, [NFS4ERR_INVAL, NFS4ERR_ATTRNOTSUPP],
>> "GETATTR(time_modify_set)")
>> + if res.status == NFS4ERR_ATTRNOTSUPP:
>> + t.fail_support("time_modify_set not a supported attribute")
>> ####################################################
>>
>
--
Chuck Lever
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] Add some tests for unsupported fattr4 attributes
2025-09-29 21:16 ` Chuck Lever
@ 2025-09-29 22:10 ` Calum Mackay
0 siblings, 0 replies; 5+ messages in thread
From: Calum Mackay @ 2025-09-29 22:10 UTC (permalink / raw)
To: Chuck Lever; +Cc: Calum Mackay, linux-nfs, Chuck Lever
On 29/09/2025 10:16 pm, Chuck Lever wrote:
> On 9/29/25 2:14 PM, Calum Mackay wrote:
>> thanks Chuck,
>>
>> I'm still catching up with pynfs patches; I'll get this (and the others
>> queued up) in asap.
>
> My patch deserves a smell test first, of course. I'm not at all sure
> this is reasonable or proper Python.
Yes, of course :)
ta,
c.
>
>
>> cheers,
>> c.
>>
>>
>> On 29/09/2025 9:16 pm, Chuck Lever wrote:
>>> From: Chuck Lever <chuck.lever@oracle.com>
>>>
>>> Linux NFSD does not implement a handful of these NFSv4.0 fattr4
>>> attributes. Ensure that NFSD's fattr4 result encoder is correctly
>>> clearing the result mask and returning NFS4_OK.
>>>
>>> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
>>> ---
>>> nfs4.0/servertests/st_getattr.py | 149 +++++++++++++++++++++++++++++++
>>> 1 file changed, 149 insertions(+)
>>>
>>> diff --git a/nfs4.0/servertests/st_getattr.py b/nfs4.0/servertests/
>>> st_getattr.py
>>> index 1c47ebf60571..d423aa1df46d 100644
>>> --- a/nfs4.0/servertests/st_getattr.py
>>> +++ b/nfs4.0/servertests/st_getattr.py
>>> @@ -521,6 +521,155 @@ def testOwnerName(t, env):
>>> t.fail_support("owner not a supported attribute")
>>> # print(res.resarray[-1].obj_attributes)
>>> +def testArchive(t, env):
>>> + """GETATTR on "archive" attribute
>>> +
>>> + FLAGS: getattr all
>>> + DEPEND: LOOKFILE
>>> + CODE: GATT11a
>>> + """
>>> + c = env.c1
>>> + ops = c.use_obj(env.opts.usefile)
>>> + ops += [c.getattr([FATTR4_ARCHIVE])]
>>> + res = c.compound(ops)
>>> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(archive)")
>>> + if res.status == NFS4ERR_ATTRNOTSUPP:
>>> + t.fail_support("archive not a supported attribute")
>>> +
>>> +def testHidden(t, env):
>>> + """GETATTR on "hidden" attribute
>>> +
>>> + FLAGS: getattr all
>>> + DEPEND: LOOKFILE
>>> + CODE: GATT11b
>>> + """
>>> + c = env.c1
>>> + ops = c.use_obj(env.opts.usefile)
>>> + ops += [c.getattr([FATTR4_HIDDEN])]
>>> + res = c.compound(ops)
>>> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(hidden)")
>>> + if res.status == NFS4ERR_ATTRNOTSUPP:
>>> + t.fail_support("hidden not a supported attribute")
>>> +
>>> +def testMimetype(t, env):
>>> + """GETATTR on "mimetype" attribute
>>> +
>>> + FLAGS: getattr all
>>> + DEPEND: LOOKFILE
>>> + CODE: GATT11c
>>> + """
>>> + c = env.c1
>>> + ops = c.use_obj(env.opts.usefile)
>>> + ops += [c.getattr([FATTR4_MIMETYPE])]
>>> + res = c.compound(ops)
>>> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(mimetype)")
>>> + if res.status == NFS4ERR_ATTRNOTSUPP:
>>> + t.fail_support("mimetype not a supported attribute")
>>> +
>>> +def testQuotaAvailHard(t, env):
>>> + """GETATTR on "quota avail hard" attribute
>>> +
>>> + FLAGS: getattr all
>>> + DEPEND: LOOKFILE
>>> + CODE: GATT11d
>>> + """
>>> + c = env.c1
>>> + ops = c.use_obj(env.opts.usefile)
>>> + ops += [c.getattr([FATTR4_QUOTA_AVAIL_HARD])]
>>> + res = c.compound(ops)
>>> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP],
>>> "GETATTR(quota_avail_hard)")
>>> + if res.status == NFS4ERR_ATTRNOTSUPP:
>>> + t.fail_support("quota_avail_hard not a supported attribute")
>>> +
>>> +def testQuotaAvailSoft(t, env):
>>> + """GETATTR on "quota avail soft" attribute
>>> +
>>> + FLAGS: getattr all
>>> + DEPEND: LOOKFILE
>>> + CODE: GATT11e
>>> + """
>>> + c = env.c1
>>> + ops = c.use_obj(env.opts.usefile)
>>> + ops += [c.getattr([FATTR4_QUOTA_AVAIL_SOFT])]
>>> + res = c.compound(ops)
>>> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP],
>>> "GETATTR(quota_avail_soft)")
>>> + if res.status == NFS4ERR_ATTRNOTSUPP:
>>> + t.fail_support("quota_avail_soft not a supported attribute")
>>> +
>>> +def testQuotaUsed(t, env):
>>> + """GETATTR on "quota used" attribute
>>> +
>>> + FLAGS: getattr all
>>> + DEPEND: LOOKFILE
>>> + CODE: GATT11f
>>> + """
>>> + c = env.c1
>>> + ops = c.use_obj(env.opts.usefile)
>>> + ops += [c.getattr([FATTR4_QUOTA_USED])]
>>> + res = c.compound(ops)
>>> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(quota_used)")
>>> + if res.status == NFS4ERR_ATTRNOTSUPP:
>>> + t.fail_support("quota_used not a supported attribute")
>>> +
>>> +def testSystem(t, env):
>>> + """GETATTR on "system" attribute
>>> +
>>> + FLAGS: getattr all
>>> + DEPEND: LOOKFILE
>>> + CODE: GATT11g
>>> + """
>>> + c = env.c1
>>> + ops = c.use_obj(env.opts.usefile)
>>> + ops += [c.getattr([FATTR4_SYSTEM])]
>>> + res = c.compound(ops)
>>> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(system)")
>>> + if res.status == NFS4ERR_ATTRNOTSUPP:
>>> + t.fail_support("system not a supported attribute")
>>> +
>>> +def testTimeBackup(t, env):
>>> + """GETATTR on "time backup" attribute
>>> +
>>> + FLAGS: getattr all
>>> + DEPEND: LOOKFILE
>>> + CODE: GATT11h
>>> + """
>>> + c = env.c1
>>> + ops = c.use_obj(env.opts.usefile)
>>> + ops += [c.getattr([FATTR4_TIME_BACKUP])]
>>> + res = c.compound(ops)
>>> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(time_backup)")
>>> + if res.status == NFS4ERR_ATTRNOTSUPP:
>>> + t.fail_support("time_backup not a supported attribute")
>>> +
>>> +def testTimeAccessSet(t, env):
>>> + """GETATTR on "time access set" attribute (write-only)
>>> +
>>> + FLAGS: getattr all
>>> + DEPEND: LOOKFILE
>>> + CODE: GATT11i
>>> + """
>>> + c = env.c1
>>> + ops = c.use_obj(env.opts.usefile)
>>> + ops += [c.getattr([FATTR4_TIME_ACCESS_SET])]
>>> + res = c.compound(ops)
>>> + check(res, [NFS4ERR_INVAL, NFS4ERR_ATTRNOTSUPP],
>>> "GETATTR(time_access_set)")
>>> + if res.status == NFS4ERR_ATTRNOTSUPP:
>>> + t.fail_support("time_access_set not a supported attribute")
>>> +
>>> +def testTimeModifySet(t, env):
>>> + """GETATTR on "time modify set" attribute (write-only)
>>> +
>>> + FLAGS: getattr all
>>> + DEPEND: LOOKFILE
>>> + CODE: GATT11j
>>> + """
>>> + c = env.c1
>>> + ops = c.use_obj(env.opts.usefile)
>>> + ops += [c.getattr([FATTR4_TIME_MODIFY_SET])]
>>> + res = c.compound(ops)
>>> + check(res, [NFS4ERR_INVAL, NFS4ERR_ATTRNOTSUPP],
>>> "GETATTR(time_modify_set)")
>>> + if res.status == NFS4ERR_ATTRNOTSUPP:
>>> + t.fail_support("time_modify_set not a supported attribute")
>>> ####################################################
>>>
>>
>
>
--
Calum Mackay
Linux Kernel Engineering
Oracle Linux and Virtualisation
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] Add some tests for unsupported fattr4 attributes
2025-09-29 20:16 [PATCH] Add some tests for unsupported fattr4 attributes Chuck Lever
2025-09-29 21:14 ` Calum Mackay
@ 2025-09-30 11:34 ` Jeff Layton
1 sibling, 0 replies; 5+ messages in thread
From: Jeff Layton @ 2025-09-30 11:34 UTC (permalink / raw)
To: Chuck Lever, Calum Mackay; +Cc: linux-nfs, Chuck Lever
On Mon, 2025-09-29 at 16:16 -0400, Chuck Lever wrote:
> From: Chuck Lever <chuck.lever@oracle.com>
>
> Linux NFSD does not implement a handful of these NFSv4.0 fattr4
> attributes. Ensure that NFSD's fattr4 result encoder is correctly
> clearing the result mask and returning NFS4_OK.
>
> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
> ---
> nfs4.0/servertests/st_getattr.py | 149 +++++++++++++++++++++++++++++++
> 1 file changed, 149 insertions(+)
>
> diff --git a/nfs4.0/servertests/st_getattr.py b/nfs4.0/servertests/st_getattr.py
> index 1c47ebf60571..d423aa1df46d 100644
> --- a/nfs4.0/servertests/st_getattr.py
> +++ b/nfs4.0/servertests/st_getattr.py
> @@ -521,6 +521,155 @@ def testOwnerName(t, env):
> t.fail_support("owner not a supported attribute")
> # print(res.resarray[-1].obj_attributes)
>
> +def testArchive(t, env):
> + """GETATTR on "archive" attribute
> +
> + FLAGS: getattr all
> + DEPEND: LOOKFILE
> + CODE: GATT11a
> + """
> + c = env.c1
> + ops = c.use_obj(env.opts.usefile)
> + ops += [c.getattr([FATTR4_ARCHIVE])]
> + res = c.compound(ops)
> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(archive)")
> + if res.status == NFS4ERR_ATTRNOTSUPP:
> + t.fail_support("archive not a supported attribute")
> +
> +def testHidden(t, env):
> + """GETATTR on "hidden" attribute
> +
> + FLAGS: getattr all
> + DEPEND: LOOKFILE
> + CODE: GATT11b
> + """
> + c = env.c1
> + ops = c.use_obj(env.opts.usefile)
> + ops += [c.getattr([FATTR4_HIDDEN])]
> + res = c.compound(ops)
> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(hidden)")
> + if res.status == NFS4ERR_ATTRNOTSUPP:
> + t.fail_support("hidden not a supported attribute")
> +
> +def testMimetype(t, env):
> + """GETATTR on "mimetype" attribute
> +
> + FLAGS: getattr all
> + DEPEND: LOOKFILE
> + CODE: GATT11c
> + """
> + c = env.c1
> + ops = c.use_obj(env.opts.usefile)
> + ops += [c.getattr([FATTR4_MIMETYPE])]
> + res = c.compound(ops)
> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(mimetype)")
> + if res.status == NFS4ERR_ATTRNOTSUPP:
> + t.fail_support("mimetype not a supported attribute")
> +
> +def testQuotaAvailHard(t, env):
> + """GETATTR on "quota avail hard" attribute
> +
> + FLAGS: getattr all
> + DEPEND: LOOKFILE
> + CODE: GATT11d
> + """
> + c = env.c1
> + ops = c.use_obj(env.opts.usefile)
> + ops += [c.getattr([FATTR4_QUOTA_AVAIL_HARD])]
> + res = c.compound(ops)
> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(quota_avail_hard)")
> + if res.status == NFS4ERR_ATTRNOTSUPP:
> + t.fail_support("quota_avail_hard not a supported attribute")
> +
> +def testQuotaAvailSoft(t, env):
> + """GETATTR on "quota avail soft" attribute
> +
> + FLAGS: getattr all
> + DEPEND: LOOKFILE
> + CODE: GATT11e
> + """
> + c = env.c1
> + ops = c.use_obj(env.opts.usefile)
> + ops += [c.getattr([FATTR4_QUOTA_AVAIL_SOFT])]
> + res = c.compound(ops)
> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(quota_avail_soft)")
> + if res.status == NFS4ERR_ATTRNOTSUPP:
> + t.fail_support("quota_avail_soft not a supported attribute")
> +
> +def testQuotaUsed(t, env):
> + """GETATTR on "quota used" attribute
> +
> + FLAGS: getattr all
> + DEPEND: LOOKFILE
> + CODE: GATT11f
> + """
> + c = env.c1
> + ops = c.use_obj(env.opts.usefile)
> + ops += [c.getattr([FATTR4_QUOTA_USED])]
> + res = c.compound(ops)
> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(quota_used)")
> + if res.status == NFS4ERR_ATTRNOTSUPP:
> + t.fail_support("quota_used not a supported attribute")
> +
> +def testSystem(t, env):
> + """GETATTR on "system" attribute
> +
> + FLAGS: getattr all
> + DEPEND: LOOKFILE
> + CODE: GATT11g
> + """
> + c = env.c1
> + ops = c.use_obj(env.opts.usefile)
> + ops += [c.getattr([FATTR4_SYSTEM])]
> + res = c.compound(ops)
> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(system)")
> + if res.status == NFS4ERR_ATTRNOTSUPP:
> + t.fail_support("system not a supported attribute")
> +
> +def testTimeBackup(t, env):
> + """GETATTR on "time backup" attribute
> +
> + FLAGS: getattr all
> + DEPEND: LOOKFILE
> + CODE: GATT11h
> + """
> + c = env.c1
> + ops = c.use_obj(env.opts.usefile)
> + ops += [c.getattr([FATTR4_TIME_BACKUP])]
> + res = c.compound(ops)
> + check(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(time_backup)")
> + if res.status == NFS4ERR_ATTRNOTSUPP:
> + t.fail_support("time_backup not a supported attribute")
> +
> +def testTimeAccessSet(t, env):
> + """GETATTR on "time access set" attribute (write-only)
> +
> + FLAGS: getattr all
> + DEPEND: LOOKFILE
> + CODE: GATT11i
> + """
> + c = env.c1
> + ops = c.use_obj(env.opts.usefile)
> + ops += [c.getattr([FATTR4_TIME_ACCESS_SET])]
> + res = c.compound(ops)
> + check(res, [NFS4ERR_INVAL, NFS4ERR_ATTRNOTSUPP], "GETATTR(time_access_set)")
> + if res.status == NFS4ERR_ATTRNOTSUPP:
> + t.fail_support("time_access_set not a supported attribute")
> +
> +def testTimeModifySet(t, env):
> + """GETATTR on "time modify set" attribute (write-only)
> +
> + FLAGS: getattr all
> + DEPEND: LOOKFILE
> + CODE: GATT11j
> + """
> + c = env.c1
> + ops = c.use_obj(env.opts.usefile)
> + ops += [c.getattr([FATTR4_TIME_MODIFY_SET])]
> + res = c.compound(ops)
> + check(res, [NFS4ERR_INVAL, NFS4ERR_ATTRNOTSUPP], "GETATTR(time_modify_set)")
> + if res.status == NFS4ERR_ATTRNOTSUPP:
> + t.fail_support("time_modify_set not a supported attribute")
>
> ####################################################
>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-09-30 11:34 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-29 20:16 [PATCH] Add some tests for unsupported fattr4 attributes Chuck Lever
2025-09-29 21:14 ` Calum Mackay
2025-09-29 21:16 ` Chuck Lever
2025-09-29 22:10 ` Calum Mackay
2025-09-30 11:34 ` Jeff Layton
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.