From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1C8C43A3E96 for ; Fri, 3 Apr 2026 13:27:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775222872; cv=none; b=fIlPfkBGvAJFCwhInxeA1kWbN1pVgJ+izMNq+UZyUKRh58QJ4OvoWDlT2RTcjYQOYXUQQIKNI96cK71GgpRmuBVKnHvAdVvl/vWw2cUZVcr/PbSD68y5huL+nVjMKvdT2YAfTy1LUbnlQU/8JYKqkRfgXbtkIMxd/3FWAcTbL3I= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775222872; c=relaxed/simple; bh=Ev0/TH1eAUEHe2n5ul6GZ1PCf/bWMcPSNtu+eajWENw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QnyS6ZYSnNdjT9z/KuWub0aJtkfeOJlQjYCv9g0lXyw9og+kdA/D8Q0VHnjSH6iT5H+hG+rYu0HAT6tcZ+Lk25WSiY8PaZDb3dJzZWJLem3LffReomIaQCuk8FE0qTSxAM51hOGVsAXMQNi4OXbTX+kcSsat3qEe5WkQxFSBzrc= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=hNCPpLB7; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="hNCPpLB7" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775222870; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2qwxLCsXrdhX145KcCLHLRp/i21IDMeySKhu0WUi9C0=; b=hNCPpLB7fNnSns3lz7WtDAejNkOtIO0970yCVz1m0ohJq7oBOGLIho98w96nBcO15EmSVz GCSFVol47GIpvaUoCWZwKAKQFedokJttpHfiJ/vV7dBG7yAgdCbqgThF/tp5pLS5GBMrs/ PZOz3QY7tsRwglQsIElLs6efCMvtOJA= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-443-5SK_uD9_PT-HcdANrDjMZA-1; Fri, 03 Apr 2026 09:27:47 -0400 X-MC-Unique: 5SK_uD9_PT-HcdANrDjMZA-1 X-Mimecast-MFC-AGG-ID: 5SK_uD9_PT-HcdANrDjMZA_1775222866 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 7997B18007FD; Fri, 3 Apr 2026 13:27:41 +0000 (UTC) Received: from aion.redhat.com (unknown [10.22.88.38]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 0FAEF1955D6D; Fri, 3 Apr 2026 13:27:41 +0000 (UTC) Received: from aion.redhat.com (localhost [IPv6:::1]) by aion.redhat.com (Postfix) with ESMTP id 5EED6749DF0; Fri, 03 Apr 2026 09:27:38 -0400 (EDT) From: Scott Mayhew To: calum.mackay@oracle.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH 5/5] pynfs: add delegation test for CB_GETATTR after sync WRITE Date: Fri, 3 Apr 2026 09:27:38 -0400 Message-ID: <20260403132738.1482011-6-smayhew@redhat.com> In-Reply-To: <20260403132738.1482011-1-smayhew@redhat.com> References: <20260403132738.1482011-1-smayhew@redhat.com> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 DELEG27 tests the scenario where a client has written data to the server while holding a write delegation, but is not *currently* holding modified data in its cache. In this case, the CB_GETATTR should not trigger an mtime update (the time_modify that client1 gets in the GETATTR after the WRITE should match the time_modify it gets in the GETATTR in the DELEGRETURN compound). Signed-off-by: Scott Mayhew --- This test currently passes if nfsd has delegated timestamps enabled and fails if it does not have them enabled (nfsd-next commit "nfsd: add a runtime switch for disabling delegated timestamps" comes in handy for testing). I posted the following kernel patch which fixes this failure: https://lore.kernel.org/linux-nfs/20260403132209.1479385-1-smayhew@redhat.com/T/#u nfs4.1/server41tests/st_delegation.py | 152 ++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) diff --git a/nfs4.1/server41tests/st_delegation.py b/nfs4.1/server41tests/st_delegation.py index 2257966..8a51eb9 100644 --- a/nfs4.1/server41tests/st_delegation.py +++ b/nfs4.1/server41tests/st_delegation.py @@ -8,6 +8,8 @@ import nfs_ops op = nfs_ops.NFS4ops() import nfs4lib import threading +import copy +import time def _got_deleg(deleg): return (deleg.delegation_type != OPEN_DELEGATE_NONE and @@ -470,3 +472,153 @@ def testDelegReadAfterClose(t, env): # cleanup: return delegation res = sess1.compound([op.putfh(fh), op.delegreturn(delegstateid)]) check(res) + +def testCbGetattrAfterSyncWrite(t, env): + """Test CB_GETATTR after a FILE_SYNC4 WRITE + + 1. Client 1 opens a file (getting a write deleg or a write attrs deleg) and + does a GETATTR + 2. Client 1 does a FILE_SYNC4 WRITE. If we got a write delegation, it + follows this up with a GETATTR. Otherwise we got a write attrs deleg + and we construct the attrs ourself. + 3. Client 2 does a GETATTR, triggering a CB_GETATTR to client 1. Client 2 + then does an OPEN, triggering a CB_RECALL to client 1. + 4. Client 1 does a PUTFH|SETATTR|GETATTR|DELEGRETURN if we have a write + attrs deleg, otherwise it does a PUTFH|GETATTR|DELEGRETURN. + + time_modify should only change between steps 1 and 2. It should not change + from steps 2 thru 4. + + FLAGS: deleg all + CODE: DELEG27 + """ + cb = threading.Event() + cbattrs = {} + def getattr_post_hook(arg, env, res): + res.obj_attributes = cbattrs + env.notify = cb.set + return res + + recall = threading.Event() + def recall_pre_hook(arg, env): + recall.stateid = arg.stateid + recall.cred = env.cred.raw_cred + env.notify = recall.set + def recall_post_hook(arg, env, res): + return res + + size = 5 + + sess1 = env.c1.new_client_session(b"%s_1" % env.testname(t)) + sess1.client.cb_post_hook(OP_CB_GETATTR, getattr_post_hook) + sess1.client.cb_pre_hook(OP_CB_RECALL, recall_pre_hook) + sess1.client.cb_post_hook(OP_CB_RECALL, recall_post_hook) + + 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] & (1 << FATTR4_OPEN_ARGUMENTS): + if caps[FATTR4_OPEN_ARGUMENTS].oa_share_access_want & OPEN_ARGS_SHARE_ACCESS_WANT_DELEG_TIMESTAMPS: + openmask |= 1<