Date: Wed, 29 Jun 2022 09:39:29 GMT From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: 65d8e97c4c23 - stable/13 - UFS: make mkdir() and link() reliable when using SU and reaching nlink limit Message-ID: <202206290939.25T9dTRK015213@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=65d8e97c4c23a0b27d9e0bc73e4150ebbb00b844 commit 65d8e97c4c23a0b27d9e0bc73e4150ebbb00b844 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2022-06-18 10:59:31 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2022-06-29 09:38:26 +0000 UFS: make mkdir() and link() reliable when using SU and reaching nlink limit PR: 165392 (cherry picked from commit 8db679af66b023802139d41e275e41a77da1c515) --- sys/ufs/ufs/ufs_vnops.c | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index b4d23545fb0b..4353c51afcbe 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -196,6 +196,35 @@ ufs_itimes(struct vnode *vp) VI_UNLOCK(vp); } +static int +ufs_sync_nlink(struct vnode *vp, struct vnode *vp1) +{ + struct inode *ip; + struct mount *mp; + int error; + + ip = VTOI(vp); + if (ip->i_nlink < UFS_LINK_MAX) + return (0); + if (!DOINGSOFTDEP(vp) || ip->i_effnlink >= UFS_LINK_MAX) + return (EMLINK); + + mp = vp->v_mount; + vfs_ref(mp); + VOP_UNLOCK(vp); + if (vp1 != NULL) + VOP_UNLOCK(vp1); + error = vfs_busy(mp, 0); + if (error == 0) { + VFS_SYNC(mp, MNT_WAIT); + vfs_unbusy(mp); + error = ERELOOKUP; + } + vfs_rel(mp); + vn_lock_pair(vp, false, vp1, false); + return (error); +} + /* * Create a regular file */ @@ -1086,11 +1115,11 @@ ufs_link(ap) error = EINVAL; goto out; } - ip = VTOI(vp); - if (ip->i_nlink >= UFS_LINK_MAX) { - error = EMLINK; + error = ufs_sync_nlink(vp, tdvp); + if (error != 0) goto out; - } + ip = VTOI(vp); + /* * The file may have been removed after namei dropped the original * lock. @@ -1950,10 +1979,9 @@ ufs_mkdir(ap) panic("ufs_mkdir: no name"); #endif dp = VTOI(dvp); - if (dp->i_nlink >= UFS_LINK_MAX) { - error = EMLINK; + error = ufs_sync_nlink(dvp, NULL); + if (error != 0) goto out; - } dmode = vap->va_mode & 0777; dmode |= IFDIR;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202206290939.25T9dTRK015213>