[PATCH pynfs v2 7/7] st_deleg: test delegated timestamps in CB_GETATTR

Jeff Layton
2024-10-14T20:50:40Z

First, query the server to get the SUPPORTED_ATTRS and OPEN_ARGUMENTS,
and determine whether delegated timestamps are supported. If they are,
request them, and test whether they are as expected.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
nfs4.1/server41tests/st_delegation.py | 42 +++++++++++++++++++++++++++++------
1 file changed, 35 insertions(+), 7 deletions(-)

diff --git a/nfs4.1/server41tests/st_delegation.py b/nfs4.1/server41tests/st_delegation.py
index 2aa73ba7acd0bd857a4fd5206b8857f980176d73..fc374e693cb4b9a9adaaf5ff15a64a02573113b0 100644
--- a/nfs4.1/server41tests/st_delegation.py
+++ b/nfs4.1/server41tests/st_delegation.py
@@ -301,22 +301,44 @@ def _testCbGetattr(t, env, change=0, size=0):
sess1 = env.c1.new_client_session(b"%s_1" % env.testname(t))
sess1.client.cb_post_hook(OP_CB_GETATTR, getattr_post_hook)

- fh, deleg = __create_file_with_deleg(sess1, env.testname(t),
- OPEN4_SHARE_ACCESS_READ |
- OPEN4_SHARE_ACCESS_WRITE |
- OPEN4_SHARE_ACCESS_WANT_WRITE_DELEG)
+ res = sess1.compound([op.putrootfh(),
+ op.getattr(nfs4lib.list2bitmap([FATTR4_SUPPORTED_ATTRS,
+ FATTR4_OPEN_ARGUMENTS]))])
+ check(res)
+ caps = res.resarray[-1].obj_attributes
+
+ openmask = (OPEN4_SHARE_ACCESS_READ |
+ OPEN4_SHARE_ACCESS_WRITE |
+ OPEN4_SHARE_ACCESS_WANT_WRITE_DELEG)
+
+ if caps[FATTR4_SUPPORTED_ATTRS] & FATTR4_OPEN_ARGUMENTS:
+ if caps[FATTR4_OPEN_ARGUMENTS].oa_share_access_want & OPEN_ARGS_SHARE_ACCESS_WANT_DELEG_TIMESTAMPS:
+ openmask |= 1<<OPEN_ARGS_SHARE_ACCESS_WANT_DELEG_TIMESTAMPS
+
+ fh, deleg = __create_file_with_deleg(sess1, env.testname(t), openmask)
print("__create_file_with_deleg: ", fh, deleg)
- attrs1 = do_getattrdict(sess1, fh, [FATTR4_CHANGE, FATTR4_SIZE])
- cbattrs = dict(attrs1)
+ attrs1 = do_getattrdict(sess1, fh, [FATTR4_CHANGE, FATTR4_SIZE,
+ FATTR4_TIME_ACCESS, FATTR4_TIME_MODIFY])
+
+ cbattrs[FATTR4_CHANGE] = attrs1[FATTR4_CHANGE]
+ cbattrs[FATTR4_SIZE] = attrs1[FATTR4_SIZE]

if change != 0:
cbattrs[FATTR4_CHANGE] += 1
if size > 0:
cbattrs[FATTR4_SIZE] = size

+ if openmask & 1<<OPEN_ARGS_SHARE_ACCESS_WANT_DELEG_TIMESTAMPS:
+ cbattrs[FATTR4_TIME_DELEG_ACCESS] = attrs1[FATTR4_TIME_ACCESS]
+ cbattrs[FATTR4_TIME_DELEG_MODIFY] = attrs1[FATTR4_TIME_MODIFY]
+ if change != 0:
+ cbattrs[FATTR4_TIME_DELEG_ACCESS].seconds += 1
+ cbattrs[FATTR4_TIME_DELEG_MODIFY].seconds += 1
+
# create a new client session and do a GETATTR
sess2 = env.c1.new_client_session(b"%s_2" % env.testname(t))
- slot = sess2.compound_async([op.putfh(fh), op.getattr(1<<FATTR4_CHANGE | 1<<FATTR4_SIZE)])
+ slot = sess2.compound_async([op.putfh(fh), op.getattr(1<<FATTR4_CHANGE | 1<<FATTR4_SIZE |
+ 1<<FATTR4_TIME_ACCESS | 1<<FATTR4_TIME_MODIFY)])

# wait for the CB_GETATTR
completed = cb.wait(2)
@@ -343,6 +365,9 @@ def testCbGetattrNoChange(t, env):
fail("Bad size: %u != %u" % (attrs1[FATTR4_SIZE], attrs2[FATTR4_SIZE]))
if attrs1[FATTR4_CHANGE] != attrs2[FATTR4_CHANGE]:
fail("Bad change attribute: %u != %u" % (attrs1[FATTR4_CHANGE], attrs2[FATTR4_CHANGE]))
+ if FATTR4_TIME_DELEG_MODIFY in attrs2:
+ if attrs1[FATTR4_TIME_MODIFY] != attrs2[FATTR4_TIME_DELEG_MODIFY]:
+ fail("Bad modify time: ", attrs1[FATTR4_TIME_MODIFY], " != ", attrs2[FATTR4_TIME_DELEG_MODIFY])

def testCbGetattrWithChange(t, env):
"""Test CB_GETATTR with simulated changes to file
@@ -359,3 +384,6 @@ def testCbGetattrWithChange(t, env):
fail("Bad size: %u != 5" % attrs2[FATTR4_SIZE])
if attrs1[FATTR4_CHANGE] == attrs2[FATTR4_CHANGE]:
fail("Bad change attribute: %u == %u" % (attrs1[FATTR4_CHANGE], attrs2[FATTR4_CHANGE]))
+ if FATTR4_TIME_DELEG_MODIFY in attrs2:
+ if attrs1[FATTR4_TIME_MODIFY] == attrs2[FATTR4_TIME_DELEG_MODIFY]:
+ fail("Bad modify time: ", attrs1[FATTR4_TIME_MODIFY], " == ", attrs2[FATTR4_TIME_DELEG_MODIFY])

--
2.47.0