From nobody Mon Sep 09 00:02:14 2024 X-Original-To: dev-commits-src-main@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 4X26TM1Btjz5WZQX; Mon, 09 Sep 2024 00:02:15 +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 "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4X26TM0Zdnz4pyW; Mon, 9 Sep 2024 00:02:15 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1725840135; 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=QRV41b/mcucFzcQeyfyMfv7WSJ7RlQWXKHlVUZdyHvA=; b=bnNWus4CF5nD1fhVX7q1ulDhPSFb5ywVY3Yagm4UaL/AbwFcOjdpIp1T2o1QWzpH2Rz36d Q+fIP3DsLu2C975ROhb/uTDbw4fA8dFhtJ6Tb2dnCQTUvj/YFUJJ0CmZiU+kOABeT9uhAo PyO8V/1lcdEobBWM0kQ8uRXGz3miW/vqveG358EnwvllnjK22WFnxrEstXwiyUiOb7H5pz +m02ooEdn4Leo3q0asIN1JGiCwOFKKDjvuitaN5cVAsoWRURu+HMyeO2hFwkFRDaGqydRq cQshXZVBqg7+VXmI6pRk9tI6ggtOXVsjQSj+lKxtx1KpPuUR5n0N3aMSc8F2jA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1725840135; a=rsa-sha256; cv=none; b=cefwM2OD/uaA2lx//p0LMbypN2lI4nH91xtG9/j/r54SYirMetpSM+Sl/wgEGOAE2mJbON kAXlpM0ir13fEoaUBgjCNcjacJcT6vj0NpLjbmr6gtyy9cVC2yzxZ6DvQkG3utZ4XDadGa V5V9gEvwv208pe8er/dpG9uslO8mYjZmWmUEisfwbTanQ+U7g8cOirjkp2b2lLcTFjFusX 9pM7KggqyTW+a61KWz32xxepbaxouj5Gfw5c47ZFevTESuYtr+dwYQmNmpt+EiKWKsUPom Ea/NVkoV893+ZhCBkSBDJjfJAcs2E7+hb0fGMN4E4r7qSnKyYzum8YrPJuXXsw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1725840135; 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=QRV41b/mcucFzcQeyfyMfv7WSJ7RlQWXKHlVUZdyHvA=; b=PmBMiMRWv0xkE6xi/1s4aQbrV/VAiSjaiJWbu974ySu5w79Hry0EVbXJbPZpy/Jfz+ElRF JGtOSj3Un6cuzhryO6i5XKMpe9FLihGU5HUSAYYq7PXHOC8ZtzSVsNuCI9M1niVxh9j9rk eqvLYlqJHtcBiBBMPgYSQZX9UEq7PBkpYfLioVm9B/IjZlWeHKeZE+G7r0CnT8NgEQMbNq p+nZCEq1sZqpobq8hXPxAwqbBcQJKOqU3YGduUZR7I5CMhkWc/3JSHddzOjAPlSI89CmUN BB1lnum4SIjI3zSD81vPVAzRN6KGITaw6b/BC4AhtfTWwypcPnhbJ0LJNPZ3Hw== 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 4X26TM08bHzgxy; Mon, 9 Sep 2024 00:02:15 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 48902EDq006683; Mon, 9 Sep 2024 00:02:14 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 48902Ejd006680; Mon, 9 Sep 2024 00:02:14 GMT (envelope-from git) Date: Mon, 9 Sep 2024 00:02:14 GMT Message-Id: <202409090002.48902Ejd006680@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: "Jason A. Harmening" Subject: git: 2ed053cde558 - main - vfs: Add IGNOREWHITEOUT flag and adopt it in UFS/unionfs List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: jah X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 2ed053cde55869d3440377d479deb00f42ba1cf8 Auto-Submitted: auto-generated The branch main has been updated by jah: URL: https://cgit.FreeBSD.org/src/commit/?id=2ed053cde55869d3440377d479deb00f42ba1cf8 commit 2ed053cde55869d3440377d479deb00f42ba1cf8 Author: Jason A. Harmening AuthorDate: 2024-08-06 04:12:36 +0000 Commit: Jason A. Harmening CommitDate: 2024-09-08 23:34:14 +0000 vfs: Add IGNOREWHITEOUT flag and adopt it in UFS/unionfs This flag is meant to request that the VOP implementation ignore whiteout entries when processing directory contents. Employ this flag (initially) in UFS when determining whether a directory is empty for the purpose of deleting it or renaming another directory over it. The previous UFS behavior was to always ignore whiteouts and to therefore always allow directories containing only whiteouts to be deleted or overwritten. This makes sense when the directory in question is being accessed through a unionfs view in which the whiteouts produce a unionfs directory that is logically empty, but it makes less sense when directly operating against the UFS directory in which case silently discarding the whiteouts may produce unexpected behavior in a current or future unionfs view. IGNOREWHITEOUT is therefore treated as opt-in and only specified by unionfs_rmdir() when invoking VOP_RMDIR() against the upper filesystem. IGNOREWHITEOUT is not currently used for unionfs rename operations, as the current implementation of unionfs_rename() simply forbids renaming over any existing upper filesystem directory in the first place. Differential Revision: https://reviews.freebsd.org/D45987 Reviewed by: olce Tested by: pho --- sys/fs/unionfs/union_vnops.c | 2 +- sys/sys/namei.h | 2 +- sys/ufs/ufs/ufs_extern.h | 2 +- sys/ufs/ufs/ufs_lookup.c | 6 ++++-- sys/ufs/ufs/ufs_vnops.c | 6 ++++-- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/sys/fs/unionfs/union_vnops.c b/sys/fs/unionfs/union_vnops.c index 3f39352ea5c0..e1048e4ba7ab 100644 --- a/sys/fs/unionfs/union_vnops.c +++ b/sys/fs/unionfs/union_vnops.c @@ -1732,7 +1732,7 @@ unionfs_rmdir(struct vop_rmdir_args *ap) } ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount); if (ump->um_whitemode == UNIONFS_WHITE_ALWAYS || lvp != NULLVP) - cnp->cn_flags |= DOWHITEOUT; + cnp->cn_flags |= (DOWHITEOUT | IGNOREWHITEOUT); int udvp_lkflags, uvp_lkflags; unionfs_forward_vop_start_pair(udvp, &udvp_lkflags, uvp, &uvp_lkflags); diff --git a/sys/sys/namei.h b/sys/sys/namei.h index 2ea4f502e8fd..1416ff983f32 100644 --- a/sys/sys/namei.h +++ b/sys/sys/namei.h @@ -159,7 +159,7 @@ int cache_fplookup(struct nameidata *ndp, enum cache_fpl_status *status, */ #define RDONLY 0x00000200 /* lookup with read-only semantics */ #define ISRESTARTED 0x00000400 /* restarted namei */ -/* UNUSED 0x00000800 */ +#define IGNOREWHITEOUT 0x00000800 /* ignore whiteouts, e.g. when checking if a dir is empty */ #define ISWHITEOUT 0x00001000 /* found whiteout */ #define DOWHITEOUT 0x00002000 /* do whiteouts */ #define WILLBEDIR 0x00004000 /* new files will be dirs; allow trailing / */ diff --git a/sys/ufs/ufs/ufs_extern.h b/sys/ufs/ufs/ufs_extern.h index b1d55ed1f180..ccd9046a5fa8 100644 --- a/sys/ufs/ufs/ufs_extern.h +++ b/sys/ufs/ufs/ufs_extern.h @@ -59,7 +59,7 @@ int ufs_bmap_seekdata(struct vnode *, off_t *); int ufs_checkpath(ino_t, ino_t, struct inode *, struct ucred *, ino_t *); void ufs_dirbad(struct inode *, doff_t, char *); int ufs_dirbadentry(struct vnode *, struct direct *, int); -int ufs_dirempty(struct inode *, ino_t, struct ucred *); +int ufs_dirempty(struct inode *, ino_t, struct ucred *, int); int ufs_extread(struct vop_read_args *); int ufs_extwrite(struct vop_write_args *); void ufs_makedirentry(struct inode *, struct componentname *, diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c index 2d6c79970c96..eaf37c58756b 100644 --- a/sys/ufs/ufs/ufs_lookup.c +++ b/sys/ufs/ufs/ufs_lookup.c @@ -1298,7 +1298,8 @@ ufs_dirrewrite(struct inode *dp, struct inode *oip, ino_t newinum, int newtype, * NB: does not handle corrupted directories. */ int -ufs_dirempty(struct inode *ip, ino_t parentino, struct ucred *cred) +ufs_dirempty(struct inode *ip, ino_t parentino, struct ucred *cred, + int skipwhiteout) { doff_t off; struct dirtemplate dbuf; @@ -1321,7 +1322,8 @@ ufs_dirempty(struct inode *ip, ino_t parentino, struct ucred *cred) if (dp->d_reclen == 0) return (0); /* skip empty entries */ - if (dp->d_ino == 0 || dp->d_ino == UFS_WINO) + if (dp->d_ino == 0 || + (skipwhiteout != 0 && dp->d_ino == UFS_WINO)) continue; /* accept only "." and ".." */ # if (BYTE_ORDER == LITTLE_ENDIAN) diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index c62583afaab6..0bca40199071 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -1625,7 +1625,8 @@ relock: */ if ((tip->i_mode & IFMT) == IFDIR) { if ((tip->i_effnlink > 2) || - !ufs_dirempty(tip, tdp->i_number, tcnp->cn_cred)) { + !ufs_dirempty(tip, tdp->i_number, tcnp->cn_cred, + (tcnp->cn_flags & IGNOREWHITEOUT) != 0)) { error = ENOTEMPTY; goto bad; } @@ -2281,7 +2282,8 @@ ufs_rmdir( error = EINVAL; goto out; } - if (!ufs_dirempty(ip, dp->i_number, cnp->cn_cred)) { + if (!ufs_dirempty(ip, dp->i_number, cnp->cn_cred, + (cnp->cn_flags & IGNOREWHITEOUT) != 0)) { error = ENOTEMPTY; goto out; }