On Fri, 2025-05-16 at 11:00 -0400, Anna Schumaker wrote: > From: Anna Schumaker <anna.schumaker@xxxxxxxxxx> > > The PTR_ERR_OR_ZERO() macro uses IS_ERR(), which checks if an error > value is a valid Linux error code. It does not take into account NFS > error codes, which are well out of the range of MAX_ERRNO. So if > _nfs4_proc_mkdir() returns -NFS4ERR_DELAY (which xfstests generic/477 was > able to consistently hit while running against a Hammerspace server), > PTR_ERR_OR_ZERO() will happily say "no, that's not an error", so we > propagate it up to the VFS who then tries to dput() it. > > Naturally, the kernel doesn't like this: > > [ 247.669307] BUG: unable to handle page fault for address: ffffffffffffd968 > [ 247.690824] RIP: 0010:lockref_put_return+0x67/0x130 > [ 247.719037] Call Trace: > [ 247.719446] <TASK> > [ 247.719806] ? __pfx_lockref_put_return+0x10/0x10 > [ 247.720538] ? _raw_spin_unlock+0x15/0x30 > [ 247.721173] ? dput+0x179/0x490 > [ 247.721682] ? vfs_mkdir+0x475/0x780 > [ 247.722259] dput+0x30/0x490 > [ 247.722730] do_mkdirat+0x158/0x310 > [ 247.723292] ? __pfx_do_mkdirat+0x10/0x10 > [ 247.723928] __x64_sys_mkdir+0xd3/0x160 > [ 247.724531] do_syscall_64+0x4b/0x120 > [ 247.725131] entry_SYSCALL_64_after_hwframe+0x76/0x7e > [ 247.725914] RIP: 0033:0x7fe0e22f3ddb > > While I was in the area, I noticed that we're discarding any errors left > unhandled by nfs4_handle_exception(). This patch fixes both of these > issues. > > Fixes: 8376583b84a1 ("nfs: change mkdir inode_operation to return alternate dentry if needed.") > Signed-off-by: Anna Schumaker <anna.schumaker@xxxxxxxxxx> > --- > fs/nfs/nfs4proc.c | 6 +++++- > 1 file changed, 5 insertions(+), 1 deletion(-) > > diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c > index c7e068b563ff..306dade146e6 100644 > --- a/fs/nfs/nfs4proc.c > +++ b/fs/nfs/nfs4proc.c > @@ -5274,13 +5274,17 @@ static struct dentry *nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry, > sattr->ia_mode &= ~current_umask(); > do { > alias = _nfs4_proc_mkdir(dir, dentry, sattr, label); > - err = PTR_ERR_OR_ZERO(alias); > + err = PTR_ERR(alias); > + if (err > 0) > + err = 0; > trace_nfs4_mkdir(dir, &dentry->d_name, err); > err = nfs4_handle_exception(NFS_SERVER(dir), err, > &exception); > } while (exception.retry); > nfs4_label_release_security(label); > > + if (err != 0) > + return ERR_PTR(err); > return alias; > } > Reviewed-by: Jeff Layton <jlayton@xxxxxxxxxx>