From nobody Fri May 05 06:38:59 2023 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4QCLch1qJ4z49qQj; Fri, 5 May 2023 06:39:00 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4QCLch0VpBz47Dc; Fri, 5 May 2023 06:39:00 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1683268740; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Zr4JRyTM8QtLCWP0PfVWfQNsPEDJp6hPGjLma28zGU0=; b=pSKrUPs/hlSmPhsJmpQS3S2W6zSssFGUeOkPTG1flptz/1Sn/cb7ZA4zV0PFyKsWIAYHCA /cuedFspaCFvWbEdazanNzcdk0yUmSC2xxx5etK7lx9LHqB05sL+eA6mJePc3feL7hdtdB hKyCKGvH/XG/Ccyc+E6zTDaJ0nDG8OIfUhFksfVJE4KHHj0wYs0bPNc5NmBPl0k2xS2CP3 lUljReAQDR5Tc/WAKGdG37vordAfHrPW+Ts4XAKXI59Qa/MoDJlNPwn8ow0eFEt+WA5YF2 A3Pl50TmQgTf1Aptkt50XvVKWhEDa5pyrbx06mCgszY6JrVJnG5acZ1Lt1dcFw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1683268740; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Zr4JRyTM8QtLCWP0PfVWfQNsPEDJp6hPGjLma28zGU0=; b=IKDrNLG8bXRgjxg/6jfhAeTj4gBHLBdHk3IesVyadHonuUhVKuuAWqjtWLshGJ1QIrcBgh BOitPQ1X+4CS6SS/fHVvA7pIT6t/01geR8qJ5g/IiulBfEwyyM/2ZzLSBqsyIitfWRQ5oN JRQg2jt4QF7vbDzNTLQk3M7xuzgtWeiPg3ci46PkH/PNq7ZGZbHVaYU0l47wqR2502jFJY caP2ooubPAW2d/4bg7jCAKnIyBlzNwFbxvuL72eIpQ6Y7fkXY8XwB2fzSyGOPbKB2+7dWQ vgr5DKtKrohTSFzYILEtlFNXXkGJsNuVuG3+hftvss8p1okGF3vHwv8nOd/c2w== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1683268740; a=rsa-sha256; cv=none; b=l5a2GF6dlIXTC4A0PY6/T2Glk8UZfnzxjdvKpgi4G6w2AFV6vWgWZPrCA9pGYO+/mgfDGy Mg3X4oA6ZosWS85sqLNGLHhCPJOrPSAyAegQMcG+ic1ZC3U1FA6dLXlXuK8hEmWehp44aN xAoYmb4OjUzbfDboUL+1v7u5BWgHMqy+wKGUlXihfi4rYgjZGxF2INPOtXQXzp00ea0FCy TiG7jcUCx+PhoVyj2MxxM8TKf61+4m4wukxYQ974kLKC8D3Nol8IrTdElPRNXBfROqSoOd iXzJ/Ck0f3VgthGl4SD+qar1p7eghE3pt+fybAeAPC9oBXXqs/sMDMCrHjlw5g== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4QCLcg6jZszkRJ; Fri, 5 May 2023 06:38:59 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 3456cxD3039558; Fri, 5 May 2023 06:38:59 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 3456cxn6039557; Fri, 5 May 2023 06:38:59 GMT (envelope-from git) Date: Fri, 5 May 2023 06:38:59 GMT Message-Id: <202305050638.3456cxn6039557@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Konstantin Belousov Subject: git: 8ba938472706 - stable/13 - vfs: Rename vfs_emptydir() to vn_dir_check_empty() List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 8ba9384727065435f699f29524980c89a9263e12 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=8ba9384727065435f699f29524980c89a9263e12 commit 8ba9384727065435f699f29524980c89a9263e12 Author: Olivier Certner AuthorDate: 2023-04-28 09:00:11 +0000 Commit: Konstantin Belousov CommitDate: 2023-05-05 06:20:58 +0000 vfs: Rename vfs_emptydir() to vn_dir_check_empty() (cherry picked from commit 2544b8e00ca1afea64b00a6ddaf7b584244ade90) --- sys/kern/vfs_mount.c | 2 +- sys/kern/vfs_subr.c | 90 --------------------------------------------------- sys/kern/vfs_vnops.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++ sys/sys/vnode.h | 2 +- 4 files changed, 93 insertions(+), 92 deletions(-) diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index 32d24fb16526..d5b137e7ffab 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -979,7 +979,7 @@ vfs_domount_first( error = ENOTDIR; } if (error == 0 && (fsflags & MNT_EMPTYDIR) != 0) - error = vfs_emptydir(vp); + error = vn_dir_check_empty(vp); if (error == 0) { VI_LOCK(vp); if ((vp->v_iflag & VI_MOUNT) == 0 && vp->v_mountedhere == NULL) diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index dbedc16f555b..2002f3b81937 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -6443,96 +6443,6 @@ filt_vfsvnode(struct knote *kn, long hint) return (res); } -/* - * Returns whether the directory is empty or not. - * If it is empty, the return value is 0; otherwise - * the return value is an error value (which may - * be ENOTEMPTY). - */ -int -vfs_emptydir(struct vnode *vp) -{ - struct thread *const td = curthread; - char *dirbuf; - size_t dirbuflen, len; - off_t off; - int eofflag, error; - struct dirent *dp; - struct vattr va; - - ASSERT_VOP_LOCKED(vp, "vfs_emptydir"); - VNASSERT(vp->v_type == VDIR, vp, ("vp is not a directory")); - - error = VOP_GETATTR(vp, &va, td->td_ucred); - if (error != 0) - return (error); - - dirbuflen = max(DEV_BSIZE, GENERIC_MAXDIRSIZ); - if (dirbuflen < va.va_blocksize) - dirbuflen = va.va_blocksize; - dirbuf = malloc(dirbuflen, M_TEMP, M_WAITOK); - - len = 0; - off = 0; - eofflag = 0; - - for (;;) { - error = vn_dir_next_dirent(vp, td, dirbuf, dirbuflen, - &dp, &len, &off, &eofflag); - if (error != 0) - goto end; - - if (len == 0) { - /* EOF */ - error = 0; - goto end; - } - - /* - * Skip whiteouts. Unionfs operates on filesystems only and not - * on hierarchies, so these whiteouts would be shadowed on the - * system hierarchy but not for a union using the filesystem of - * their directories as the upper layer. Additionally, unionfs - * currently transparently exposes union-specific metadata of - * its upper layer, meaning that whiteouts can be seen through - * the union view in empty directories. Taking into account - * these whiteouts would then prevent mounting another - * filesystem on such effectively empty directories. - */ - if (dp->d_type == DT_WHT) - continue; - - /* - * Any file in the directory which is not '.' or '..' indicates - * the directory is not empty. - */ - switch (dp->d_namlen) { - case 2: - if (dp->d_name[1] != '.') { - /* Can't be '..' (nor '.') */ - error = ENOTEMPTY; - goto end; - } - /* FALLTHROUGH */ - case 1: - if (dp->d_name[0] != '.') { - /* Can't be '..' nor '.' */ - error = ENOTEMPTY; - goto end; - } - break; - - default: - error = ENOTEMPTY; - goto end; - } - } - -end: - free(dirbuf, M_TEMP); - return (error); -} - int vfs_read_dirent(struct vop_readdir_args *ap, struct dirent *dp, off_t off) { diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 8ad66be142b2..dfaa6868c567 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -3757,6 +3757,97 @@ out: return (error); } +/* + * Checks whether a directory is empty or not. + * + * If the directory is empty, returns 0, and if it is not, ENOTEMPTY. Other + * values are genuine errors preventing the check. + */ +int +vn_dir_check_empty(struct vnode *vp) +{ + struct thread *const td = curthread; + char *dirbuf; + size_t dirbuflen, len; + off_t off; + int eofflag, error; + struct dirent *dp; + struct vattr va; + + ASSERT_VOP_LOCKED(vp, "vfs_emptydir"); + VNPASS(vp->v_type == VDIR, vp); + + error = VOP_GETATTR(vp, &va, td->td_ucred); + if (error != 0) + return (error); + + dirbuflen = max(DEV_BSIZE, GENERIC_MAXDIRSIZ); + if (dirbuflen < va.va_blocksize) + dirbuflen = va.va_blocksize; + dirbuf = malloc(dirbuflen, M_TEMP, M_WAITOK); + + len = 0; + off = 0; + eofflag = 0; + + for (;;) { + error = vn_dir_next_dirent(vp, td, dirbuf, dirbuflen, + &dp, &len, &off, &eofflag); + if (error != 0) + goto end; + + if (len == 0) { + /* EOF */ + error = 0; + goto end; + } + + /* + * Skip whiteouts. Unionfs operates on filesystems only and + * not on hierarchies, so these whiteouts would be shadowed on + * the system hierarchy but not for a union using the + * filesystem of their directories as the upper layer. + * Additionally, unionfs currently transparently exposes + * union-specific metadata of its upper layer, meaning that + * whiteouts can be seen through the union view in empty + * directories. Taking into account these whiteouts would then + * prevent mounting another filesystem on such effectively + * empty directories. + */ + if (dp->d_type == DT_WHT) + continue; + + /* + * Any file in the directory which is not '.' or '..' indicates + * the directory is not empty. + */ + switch (dp->d_namlen) { + case 2: + if (dp->d_name[1] != '.') { + /* Can't be '..' (nor '.') */ + error = ENOTEMPTY; + goto end; + } + /* FALLTHROUGH */ + case 1: + if (dp->d_name[0] != '.') { + /* Can't be '..' nor '.' */ + error = ENOTEMPTY; + goto end; + } + break; + + default: + error = ENOTEMPTY; + goto end; + } + } + +end: + free(dirbuf, M_TEMP); + return (error); +} + static u_long vn_lock_pair_pause_cnt; SYSCTL_ULONG(_debug, OID_AUTO, vn_lock_pair_pause, CTLFLAG_RD, diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 7b15cb95f63f..543eb06f2f16 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -1099,8 +1099,8 @@ struct dirent; int vn_dir_next_dirent(struct vnode *vp, struct thread *td, char *dirbuf, size_t dirbuflen, struct dirent **dpp, size_t *len, off_t *off, int *eofflag); +int vn_dir_check_empty(struct vnode *vp); int vfs_read_dirent(struct vop_readdir_args *ap, struct dirent *dp, off_t off); -int vfs_emptydir(struct vnode *vp); int vfs_unixify_accmode(accmode_t *accmode);