diff options
| author | Trond Myklebust <trond.myklebust@hammerspace.com> | 2026-01-06 11:54:32 -0500 |
|---|---|---|
| committer | Trond Myklebust <trond.myklebust@hammerspace.com> | 2026-01-07 12:28:26 -0500 |
| commit | df56ddd057424d21483bd0bee4da3632706d6606 (patch) | |
| tree | 17514a013c8843ebe91065aeddc621266ff569c1 /fs | |
| parent | 3f77eda548c82564ae4a23c76b51d36c6e39c865 (diff) | |
NFSv4.x: Directory delegations don't require any state recovery
The state recovery code in nfs_end_delegation_return() is intended to
allow regular files to recover cached open and lock state. It has no
function for directory delegations, and may cause corruption.
Fixes: 156b09482933 ("NFS: Request a directory delegation on ACCESS, CREATE, and UNLINK")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/nfs/delegation.c | 5 | ||||
| -rw-r--r-- | fs/nfs/nfs4state.c | 6 |
2 files changed, 10 insertions, 1 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 2248e3ad089a..c9fa4c1f68fc 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -581,6 +581,10 @@ static int nfs_end_delegation_return(struct inode *inode, struct nfs_delegation if (delegation == NULL) return 0; + /* Directory delegations don't require any state recovery */ + if (!S_ISREG(inode->i_mode)) + goto out_return; + if (!issync) mode |= O_NONBLOCK; /* Recall of any remaining application leases */ @@ -604,6 +608,7 @@ static int nfs_end_delegation_return(struct inode *inode, struct nfs_delegation goto out; } +out_return: err = nfs_do_return_delegation(inode, delegation, issync); out: /* Refcount matched in nfs_start_delegation_return_locked() */ diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 01179f7de322..dba51c622cf3 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -1445,6 +1445,8 @@ void nfs_inode_find_state_and_recover(struct inode *inode, struct nfs4_state *state; bool found = false; + if (!S_ISREG(inode->i_mode)) + goto out; rcu_read_lock(); list_for_each_entry_rcu(ctx, &nfsi->open_files, list) { state = ctx->state; @@ -1466,7 +1468,7 @@ void nfs_inode_find_state_and_recover(struct inode *inode, found = true; } rcu_read_unlock(); - +out: nfs_inode_find_delegation_state_and_recover(inode, stateid); if (found) nfs4_schedule_state_manager(clp); @@ -1478,6 +1480,8 @@ static void nfs4_state_mark_open_context_bad(struct nfs4_state *state, int err) struct nfs_inode *nfsi = NFS_I(inode); struct nfs_open_context *ctx; + if (!S_ISREG(inode->i_mode)) + return; rcu_read_lock(); list_for_each_entry_rcu(ctx, &nfsi->open_files, list) { if (ctx->state != state) |
