From nobody Fri Apr 28 19:37:41 2023 X-Original-To: dev-commits-src-all@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 4Q7NDQ1jN9z47spX; Fri, 28 Apr 2023 19:37:42 +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 4Q7NDQ0nxpz3FbB; Fri, 28 Apr 2023 19:37:42 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1682710662; 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=6P4pxKc1apSif3lYPF5x0PZND1Q0i0BVEuLAbs35AIM=; b=aWjx603yn8wv/Fo4B7uWdFw41asWfgCei+lmSMQS5OrErXxDwuZDMUpopq8ngx+aSy56MH qEpGZn4egS5zj/x4MFpn2Xz2cSsqDX7zdQyl2WHlc4H/8/aah0MiVqc+Rgv70tEqnlQig7 6wO3BJJV67ZebvNKReut55g7lxUJP5q0g878yL+otcBEgoTpLeJWqXVUckgjq5VRD0puGE Xe4RHMlJ66e3qULoxDxYfRwQoA8dyfGYExSzT627wcuPBQDWqN1QQAwbJtUS0t9D4ojXx7 Lo6nczBLvwecFOy87eC/vnZJOizJfbK2bTmqRSjQGtoDsfVxiwqhGAbXxHANeg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1682710662; 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=6P4pxKc1apSif3lYPF5x0PZND1Q0i0BVEuLAbs35AIM=; b=Zqu1Z7ClY2NcF5BT5LiAhqEZ78nF/34IyTLeMfljT7zQQRMU3y2l5+HVc6kJ91Z/1P6qj1 WIo/oFAdlL9ZVzgbF4YhoUOGfLNjq0PMMpq1OoH891AvNiStB4bQwBOJXTFzg6J5vzz3fa giMLq/NlKBfp0wpHGjWLa9ascav+Lc6kt6XEr9HprNiorULPExbr4syLvWSQR/ZoUW2s+p PV0FwMNpK0NBL5ZneymVhKofK+I6k0uKGjWYMKerZgND5x2XsqhfMr4wQ001g8wpoHZm4E QK1fMCzyz+oiWLZRnWAmwWmbYQHcgbVHYi/kjs8UhoondynmBK2z0PlvPAJD2g== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1682710662; a=rsa-sha256; cv=none; b=u0dvUnp8abNve/cd6vqqxOvzfAygkTzmpX5i6qkFveMfx/yLlXGy41MXMp0HMi+l0ubGQp 01xMGlJCDXqmug0mqv5AdW7DOIJ4wHuH+Do2v/GDD4KX4iFCMX8KzZq7R5ahIMWBtTCGa/ tXl6CKJv2pygVldVxWi2loRNLH8+JzROe2qa7dpmWiafpP/m1+qCc0NbqLpJg0dvEijpqE rAKkQXC5d6TGfL8Co2NB4/001KvG2F+qPy1lSn3tuOBAeM4+I9s/CiQ25K+QyUXdhWhn6a D+W6am714mfEISIHuRwiGaJ9UbqI+sZtSjZygdHleklcnYErYLF40z5SJZxfYw== 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 4Q7NDP6hdqz1C3N; Fri, 28 Apr 2023 19:37:41 +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 33SJbfCm075111; Fri, 28 Apr 2023 19:37:41 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 33SJbfIg075110; Fri, 28 Apr 2023 19:37:41 GMT (envelope-from git) Date: Fri, 28 Apr 2023 19:37:41 GMT Message-Id: <202304281937.33SJbfIg075110@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Konstantin Belousov Subject: git: 2544b8e00ca1 - main - vfs: Rename vfs_emptydir() to vn_dir_check_empty() List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@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/main X-Git-Reftype: branch X-Git-Commit: 2544b8e00ca1afea64b00a6ddaf7b584244ade90 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=2544b8e00ca1afea64b00a6ddaf7b584244ade90 commit 2544b8e00ca1afea64b00a6ddaf7b584244ade90 Author: Olivier Certner AuthorDate: 2023-04-28 09:00:11 +0000 Commit: Konstantin Belousov CommitDate: 2023-04-28 19:37:35 +0000 vfs: Rename vfs_emptydir() to vn_dir_check_empty() No functional change. While here, adapt comments to style(9). Reviewed by: kib MFC after: 1 week --- 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 bf532df335bf..e7f9eab33158 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -1160,7 +1160,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 3c783f7326d0..9901a20172a4 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -6382,96 +6382,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"); - 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); -} - 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 d2b1a9b0570b..33cb3ebed60f 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -3897,6 +3897,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 8403dd8c035b..7ba95de34b5d 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -1102,8 +1102,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);