diff options
| author | NeilBrown <neil@brown.name> | 2025-11-13 11:18:37 +1100 |
|---|---|---|
| committer | Christian Brauner <brauner@kernel.org> | 2025-11-14 13:15:58 +0100 |
| commit | fe497f0759e0efb949f9480911d00b6045c21f50 (patch) | |
| tree | 1b0fa2942903931da22de557d9641b6c6a1c23e0 /fs/nfsd | |
| parent | f046fbb4d81d1b0c4a169707411e3cd540c03354 (diff) | |
VFS: change vfs_mkdir() to unlock on failure.
vfs_mkdir() already drops the reference to the dentry on failure but it
leaves the parent locked.
This complicates end_creating() which needs to unlock the parent even
though the dentry is no longer available.
If we change vfs_mkdir() to unlock on failure as well as releasing the
dentry, we can remove the "parent" arg from end_creating() and simplify
the rules for calling it.
Note that cachefiles_get_directory() can choose to substitute an error
instead of actually calling vfs_mkdir(), for fault injection. In that
case it needs to call end_creating(), just as vfs_mkdir() now does on
error.
ovl_create_real() will now unlock on error. So the conditional
end_creating() after the call is removed, and end_creating() is called
internally on error.
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Tested-by: syzbot@syzkaller.appspotmail.com
Signed-off-by: NeilBrown <neil@brown.name>
Link: https://patch.msgid.link/20251113002050.676694-15-neilb@ownmail.net
Signed-off-by: Christian Brauner <brauner@kernel.org>
Diffstat (limited to 'fs/nfsd')
| -rw-r--r-- | fs/nfsd/nfs3proc.c | 2 | ||||
| -rw-r--r-- | fs/nfsd/nfs4proc.c | 2 | ||||
| -rw-r--r-- | fs/nfsd/nfs4recover.c | 2 | ||||
| -rw-r--r-- | fs/nfsd/nfsproc.c | 2 | ||||
| -rw-r--r-- | fs/nfsd/vfs.c | 8 |
5 files changed, 8 insertions, 8 deletions
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index e2aac0def2cb..6b39e4aff959 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c @@ -364,7 +364,7 @@ set_attr: status = nfsd_create_setattr(rqstp, fhp, resfhp, &attrs); out: - end_creating(child, parent); + end_creating(child); out_write: fh_drop_write(fhp); return status; diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index b2c95e8e7c68..524cb07a477c 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -376,7 +376,7 @@ set_attr: if (attrs.na_aclerr) open->op_bmval[0] &= ~FATTR4_WORD0_ACL; out: - end_creating(child, parent); + end_creating(child); nfsd_attrs_free(&attrs); out_write: fh_drop_write(fhp); diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index 3eefaa2202e3..18c08395b273 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c @@ -215,7 +215,7 @@ nfsd4_create_clid_dir(struct nfs4_client *clp) if (IS_ERR(dentry)) status = PTR_ERR(dentry); out_end: - end_creating(dentry, dir); + end_creating(dentry); out: if (status == 0) { if (nn->in_grace) diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c index ee1b16e921fd..28f03a6a3cc3 100644 --- a/fs/nfsd/nfsproc.c +++ b/fs/nfsd/nfsproc.c @@ -421,7 +421,7 @@ nfsd_proc_create(struct svc_rqst *rqstp) } out_unlock: - end_creating(dchild, dirfhp->fh_dentry); + end_creating(dchild); out_write: fh_drop_write(dirfhp); done: diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 62109885d4db..6e9a57863904 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1589,7 +1589,7 @@ nfsd_create_locked(struct svc_rqst *rqstp, struct svc_fh *fhp, out: if (!err) fh_fill_post_attrs(fhp); - end_creating(dchild, dentry); + end_creating(dchild); return err; out_nfserr: @@ -1646,7 +1646,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, return err; out_unlock: - end_creating(dchild, dentry); + end_creating(dchild); return err; } @@ -1747,7 +1747,7 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, nfsd_create_setattr(rqstp, fhp, resfhp, attrs); fh_fill_post_attrs(fhp); out_unlock: - end_creating(dnew, dentry); + end_creating(dnew); if (!err) err = nfserrno(commit_metadata(fhp)); if (!err) @@ -1824,7 +1824,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, host_err = vfs_link(dold, &nop_mnt_idmap, dirp, dnew, NULL); fh_fill_post_attrs(ffhp); out_unlock: - end_creating(dnew, ddir); + end_creating(dnew); if (!host_err) { host_err = commit_metadata(ffhp); if (!host_err) |
