nfsd: update mtime/ctime on CLONE in presense of delegated attributes
Subsystems (3)
Chuck Lever
maintainerPATCH 1/3 nfsd: update mtime/ctime on CLONE in presense of delegated attributes
From: Olga Kornievskaia <[email protected]>
commit 2863bac7f49c4acd80a048ce52506a2b9c8db015 upstream.
When delegated attributes are given on open, the file is opened with NOCMTIME and modifying operations do not update mtime/ctime as to not get out-of-sync with the client's delegated view. However, for CLONE operation, the server should update its view of mtime/ctime and reflect that in any GETATTR queries.
--- fs/nfsd/nfs4proc.c | 3 +++ fs/nfsd/nfs4state.c | 44 +++++++++++++++++++++++++++++--------------- fs/nfsd/state.h | 1 + 3 files changed, 33 insertions(+), 15 deletions(-)
fs/nfsd/nfs4proc.c +3 -0
@@ -1350,6 +1350,9 @@ nfsd4_clone(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, dst, clone->cl_dst_pos, clone->cl_count, EX_ISSYNC(cstate->current_fh.fh_export)); +if (!status && (READ_ONCE (dst->nf_file->f_mode) &FMODE_NOCMTIME ) !=0 ) +nfsd_update_cmtime_attr (dst->nf_file,0 ); +nfsd_file_put (dst);nfsd_file_put (src); out:
fs/nfsd/nfs4state.c +29 -15
59 lines not on this page · raw message
fs/nfsd/state.h +1 -0
@@ -831,6 +831,7 @@ extern void nfsd4_shutdown_callback(struct nfs4_client *);extern void nfsd4_shutdown_copy (struct nfs4_client *clp);void nfsd4_async_copy_reaper (struct nfsd_net *nn);bool nfsd4_has_active_async_copies (struct nfs4_client *clp); +void nfsd_update_cmtime_attr (struct file *f,unsigned int flags);extern struct nfs4_client_reclaim *nfs4_client_to_reclaim (struct xdr_netobj name,struct xdr_netobj princhash,struct nfsd_net *nn);extern bool nfs4_has_reclaimed_state (struct xdr_netobj name,struct nfsd_net *nn);
Signature · 1 line
2.54.0
Chuck Lever
maintainerPATCH 2/3 nfsd: update mtime/ctime on COPY in presence of delegated attributes
From: Olga Kornievskaia <[email protected]>
commit 4183cf383b6faec17a0882b84cd2d901dba62b16 upstream.
When delegated attributes are given on open, the file is opened with NOCMTIME and modifying operations do not update mtime/ctime as to not get out-of-sync with the client's delegated view. However, for COPY operation, the server should update its view of mtime/ctime and reflect that in any GETATTR queries.
--- fs/nfsd/nfs4proc.c | 11 ++++++++++- fs/nfsd/xdr4.h | 1 + 2 files changed, 11 insertions(+), 1 deletion(-)
fs/nfsd/nfs4proc.c +10 -1
@@ -1956,8 +1956,10 @@ static int nfsd4_do_async_copy(void *data)set_bit (NFSD4_COPY_F_COMPLETED , ©->cp_flags);trace_nfsd_copy_async_done (copy); -nfsd4_send_cb_offload (copy);atomic_dec (©->cp_nn->pending_async_copies); +if (copy->cp_res.wr_bytes_written >0 && copy->attr_update) +nfsd_update_cmtime_attr (copy->nf_dst->nf_file,0 ); +nfsd4_send_cb_offload (copy);return 0 ; }
@@ -2017,6 +2019,9 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,memcpy (&result->cb_stateid, ©->cp_stateid.cs_stid,sizeof (result->cb_stateid));dup_copy_fields (copy, async_copy); +if ((READ_ONCE (copy->nf_dst->nf_file->f_mode) & +FMODE_NOCMTIME ) !=0 ) + async_copy->attr_update = true;memcpy (async_copy->cp_cb_offload.co_referring_sessionid.data, cstate->session->se_sessionid.data,NFS4_MAX_SESSIONID_LEN );
@@ -2035,6 +2040,10 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, }else { status =nfsd4_do_copy (copy, copy->nf_src->nf_file, copy->nf_dst->nf_file, true); +if ((READ_ONCE (copy->nf_dst->nf_file->f_mode) & +FMODE_NOCMTIME ) !=0 && + copy->cp_res.wr_bytes_written >0 ) +nfsd_update_cmtime_attr (copy->nf_dst->nf_file,0 ); } out:trace_nfsd_copy_done (copy, status);
fs/nfsd/xdr4.h +1 -0
@@ -745,6 +745,7 @@ struct nfsd4_copy {struct nfsd_file *nf_src;struct nfsd_file *nf_dst; +bool attr_update;copy_stateid_t cp_stateid;
Signature · 1 line
2.54.0
Chuck Lever
maintainerPATCH 3/3 nfsd: release layout stid on setlease failure
In reply to Chuck Levercommit 30d55c8aabb261bc3f427d6b9aae7ef6206063f9 upstream.
nfs4_alloc_stid() publishes the new stid into cl->cl_stateids via idr_alloc_cyclic() under cl_lock before returning to nfsd4_alloc_layout_stateid(). When nfsd4_layout_setlease() then fails, the error path frees the layout stateid directly with kmem_cache_free() without ever calling idr_remove(), leaving the IDR slot pointing at freed slab memory. Any subsequent IDR walker (states_show, client teardown) dereferences the dangling pointer.
The correct teardown for an IDR-published stid is nfs4_put_stid(), which removes the IDR slot under cl_lock, dispatches sc_free (nfsd4_free_layout_stateid) to release ls->ls_file via nfsd4_close_layout(), and drops the nfs4_file reference in its tail.
A second issue blocks that switch: nfsd4_free_layout_stateid() unconditionally inspects ls->ls_fence_work via delayed_work_pending() under ls_lock, but INIT_DELAYED_WORK(&ls->ls_fence_work, ...) currently runs only after the setlease call. On the setlease-failure path the destructor would touch an uninitialized delayed_work.
nfsd4_alloc_layout_stateid()
nfs4_alloc_stid() /* idr_alloc_cyclic under cl_lock */
nfsd4_layout_setlease() /* fails */
nfs4_put_stid()
nfsd4_free_layout_stateid()
delayed_work_pending(&ls->ls_fence_work) /* needs INIT */
nfsd4_close_layout() /* nfsd_file_put(ls->ls_file) */
put_nfs4_file()Fix by hoisting the ls_fenced / ls_fence_delay / INIT_DELAYED_WORK initialization above the nfsd4_layout_setlease() call, and replace the manual nfsd_file_put + put_nfs4_file + kmem_cache_free cleanup with a single nfs4_put_stid(stp).
--- fs/nfsd/nfs4layouts.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
fs/nfsd/nfs4layouts.c +1 -3
@@ -256,9 +256,7 @@ nfsd4_alloc_layout_stateid(struct nfsd4_compound_state *cstate,BUG_ON (!ls->ls_file);if (nfsd4_layout_setlease (ls)) { -nfsd_file_put (ls->ls_file); -put_nfs4_file (fp); -kmem_cache_free (nfs4_layout_stateid_cache, ls); +nfs4_put_stid (stp);return NULL ; }
Signature · 1 line
2.54.0
Chuck Lever
maintainerRe: [PATCH 6.18.y 3/3] nfsd: release layout stid on setlease failure
Please note: The correct Author for this patch is "Chris Mason <[email protected]>"
Quoted 67 lines · Chuck Lever
commit
30d55c8aabb261bc3f427d6b9aae7ef6206063f9upstream.
nfs4_alloc_stid()publishes the new stid intocl->cl_stateidsviaidr_alloc_cyclic()undercl_lockbefore returning tonfsd4_alloc_layout_stateid(). Whennfsd4_layout_setlease()then fails, the error path frees the layout stateid directly withkmem_cache_free()without ever callingidr_remove(), leaving the IDR slot pointing at freed slab memory. Any subsequent IDR walker (states_show, client teardown) dereferences the dangling pointer.The correct teardown for an IDR-published stid is
nfs4_put_stid(), which removes the IDR slot undercl_lock, dispatchessc_free(nfsd4_free_layout_stateid) to releasels->ls_filevianfsd4_close_layout(), and drops thenfs4_filereference in its tail.A second issue blocks that switch:
nfsd4_free_layout_stateid()unconditionally inspectsls->ls_fence_workviadelayed_work_pending()underls_lock, butINIT_DELAYED_WORK(&ls->ls_fence_work, ...)currently runs only after the setlease call. On the setlease-failure path the destructor would touch an uninitializeddelayed_work.nfsd4_alloc_layout_stateid() nfs4_alloc_stid() /* idr_alloc_cyclic under cl_lock */ nfsd4_layout_setlease() /* fails */ nfs4_put_stid() nfsd4_free_layout_stateid() delayed_work_pending(&ls->ls_fence_work) /* needs INIT */ nfsd4_close_layout() /* nfsd_file_put(ls->ls_file) */ put_nfs4_file()Fix by hoisting the
ls_fenced/ls_fence_delay/INIT_DELAYED_WORKinitialization above thenfsd4_layout_setlease()call, and replace the manualnfsd_file_put+put_nfs4_file+kmem_cache_freecleanup with a singlenfs4_put_stid(stp).Fixes c5c707f96fc9 ("nfsd: implement pNFS layout recalls")Assisted-by kres (claude-opus-4-7)Signed-off-by Chris Mason <[email protected]>Reviewed-by Jeff Layton <[email protected]>Signed-off-by Chuck Lever <[email protected]>[ cel: drop fence_work init hoist absent from 6.18.y ]Signed-off-by Chuck Lever <[email protected]>--- fs/nfsd/nfs4layouts.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)fs/nfsd/nfs4layouts.c +1
-3@@ -256,9 +256,7 @@ nfsd4_alloc_layout_stateid(struct nfsd4_compound_state *cstate,BUG_ON (!ls->ls_file);if (nfsd4_layout_setlease (ls)) { -nfsd_file_put (ls->ls_file); -put_nfs4_file (fp); -kmem_cache_free (nfs4_layout_stateid_cache, ls); +nfs4_put_stid (stp);return NULL ; }Signature · 2 lines
-- 2.54.0
Signature · 1 line
Chuck Lever
Quoted 3 lines · Chuck Lever
From: Olga Kornievskaia <[email protected]>
commit
2863bac7f49c4acd80a048ce52506a2b9c8db015upstream.
Queued the series for 6.18.y, with the author of 3/3 fixed up to Chris Mason per your follow-up. Thanks!
Signature · 2 lines
Thanks, Sasha