summaryrefslogtreecommitdiff
path: root/fs/nfsd
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2025-12-30 17:56:26 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2025-12-30 17:56:26 -0800
commitc8ebd433459bcbf068682b09544e830acd7ed222 (patch)
treef53d063308258f725ee8b68e6eb6f64a041147fa /fs/nfsd
parentdbf8fe85a16a33d6b6bd01f2bc606fc017771465 (diff)
parent1f941b2c23fd34c6f3b76d36f9d0a2528fa92b8f (diff)
Merge tag 'nfsd-6.19-2' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux
Pull nfsd fixes from Chuck Lever: "A set of NFSD fixes that arrived just a bit late for the 6.19 merge window. Regression fix: - Avoid unnecessarily breaking a timestamp delegation Stable fixes: - Fix a crasher in nlm4svc_proc_test() - Fix nfsd_file reference leak during write delegation - Fix error flow in client_states_open()" * tag 'nfsd-6.19-2' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux: nfsd: Drop the client reference in client_states_open() nfsd: use ATTR_DELEG in nfsd4_finalize_deleg_timestamps() nfsd: fix nfsd_file reference leak in nfsd4_add_rdaccess_to_wrdeleg() lockd: fix vfs_test_lock() calls
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/nfs4state.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 808c24fb5c9a..a6e8a1f27133 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1218,13 +1218,15 @@ static void put_deleg_file(struct nfs4_file *fp)
if (nf)
nfsd_file_put(nf);
- if (rnf)
+ if (rnf) {
+ nfsd_file_put(rnf);
nfs4_file_put_access(fp, NFS4_SHARE_ACCESS_READ);
+ }
}
static void nfsd4_finalize_deleg_timestamps(struct nfs4_delegation *dp, struct file *f)
{
- struct iattr ia = { .ia_valid = ATTR_ATIME | ATTR_CTIME | ATTR_MTIME };
+ struct iattr ia = { .ia_valid = ATTR_ATIME | ATTR_CTIME | ATTR_MTIME | ATTR_DELEG };
struct inode *inode = file_inode(f);
int ret;
@@ -3097,8 +3099,10 @@ static int client_states_open(struct inode *inode, struct file *file)
return -ENXIO;
ret = seq_open(file, &states_seq_ops);
- if (ret)
+ if (ret) {
+ drop_client(clp);
return ret;
+ }
s = file->private_data;
s->private = clp;
return 0;
@@ -6231,10 +6235,14 @@ nfsd4_add_rdaccess_to_wrdeleg(struct svc_rqst *rqstp, struct nfsd4_open *open,
fp = stp->st_stid.sc_file;
spin_lock(&fp->fi_lock);
__nfs4_file_get_access(fp, NFS4_SHARE_ACCESS_READ);
- fp = stp->st_stid.sc_file;
- fp->fi_fds[O_RDONLY] = nf;
- fp->fi_rdeleg_file = nf;
+ if (!fp->fi_fds[O_RDONLY]) {
+ fp->fi_fds[O_RDONLY] = nf;
+ nf = NULL;
+ }
+ fp->fi_rdeleg_file = nfsd_file_get(fp->fi_fds[O_RDONLY]);
spin_unlock(&fp->fi_lock);
+ if (nf)
+ nfsd_file_put(nf);
}
return true;
}