#
2ed053cd |
| 06-Aug-2024 |
Jason A. Harmening <jah@FreeBSD.org> |
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 (init
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
show more ...
|
#
53a777bb |
| 14-Jun-2024 |
Jason A. Harmening <jah@FreeBSD.org> |
unionfs: do not create a new status object during vop_close()
Split the portion of unionfs_get_node_status() that searches for an existing status object into a new helper function, unionfs_find_node
unionfs: do not create a new status object during vop_close()
Split the portion of unionfs_get_node_status() that searches for an existing status object into a new helper function, unionfs_find_node_status(), and use that in unionfs_close().
Additionally, modify unionfs_close() to accept a NULL status object if unionfs_find_node_status() does not find a matching status object. This can happen due to the unconditional VOP_CLOSE() operation issued by vgonel().
Differential Revision: https://reviews.freebsd.org/D45398 Reviewed by: olce Tested by: pho
show more ...
|
Revision tags: release/14.1.0, release/13.3.0 |
|
#
eb60ff1e |
| 28-Feb-2024 |
Jason A. Harmening <jah@FreeBSD.org> |
unionfs: rework locking scheme to only lock a single vnode
Instead of locking both the lower and upper vnodes, which is both complex and deadlock-prone, only lock the upper vnode, or the lower vnode
unionfs: rework locking scheme to only lock a single vnode
Instead of locking both the lower and upper vnodes, which is both complex and deadlock-prone, only lock the upper vnode, or the lower vnode if no upper vnode is present.
In most cases this is all that is needed; for the cases in which both vnodes do need to be locked, this change also employs deadlock- avoiding techniques such as LK_NOWAIT and vn_lock_pair().
There are still some corner cases in which the current implementation ends up taking multiple vnode locks across different filesystems without taking special steps to avoid deadlock; those cases have been noted in the comments.
Differential Revision: https://reviews.freebsd.org/D45398 Reviewed by: olce Tested by: pho
show more ...
|
#
05e8ab62 |
| 18-Feb-2024 |
Jason A. Harmening <jah@FreeBSD.org> |
unionfs_rename: fix numerous locking issues
There are a few places in which unionfs_rename() accesses fvp's private data without holding the necessary lock/interlock. Moreover, the implementation c
unionfs_rename: fix numerous locking issues
There are a few places in which unionfs_rename() accesses fvp's private data without holding the necessary lock/interlock. Moreover, the implementation completely fails to handle the case in which fdvp is not the same as tdvp; in this case it simply fails to lock fdvp at all. Finally, it locks fvp while potentially already holding tvp's lock, but makes no attempt to deal with possible LOR there.
Fix this by optimistically using the vnode interlock to protect the short accesses to fdvp and fvp private data, sequentially. If a file copy or shadow directory creation is required to prepare the upper FS for the rename operation, the interlock must be dropped and fdvp/fvp locked as necessary.
Additionally, use ERELOOKUP (as suggested by kib@) to simplify the locking logic and eliminate unionfs_relookup() calls for file-copy/ shadow-directory cases that require tdvp's lock to be dropped.
Reviewed by: kib (earlier version), olce Tested by: pho Differential Revision: https://reviews.freebsd.org/D44788
show more ...
|
#
b18029bc |
| 18-Feb-2024 |
Jason A. Harmening <jah@FreeBSD.org> |
unionfs_lookup(): fix wild accesses to vnode private data
There are a few spots in which unionfs_lookup() accesses unionfs vnode private data without holding the corresponding vnode lock or interloc
unionfs_lookup(): fix wild accesses to vnode private data
There are a few spots in which unionfs_lookup() accesses unionfs vnode private data without holding the corresponding vnode lock or interlock.
Reviewed by: kib, olce MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D44601
show more ...
|
#
eee6217b |
| 03-Feb-2024 |
Jason A. Harmening <jah@FreeBSD.org> |
unionfs: implement VOP_UNP_* and remove special VSOCK vnode handling
unionfs has a bunch of clunky special-case code to avoid creating unionfs wrapper vnodes for AF_UNIX sockets. This was added in
unionfs: implement VOP_UNP_* and remove special VSOCK vnode handling
unionfs has a bunch of clunky special-case code to avoid creating unionfs wrapper vnodes for AF_UNIX sockets. This was added in 2008 to address PR 118346, but in the intervening years the VOP_UNP_* operations have been added to provide a clean interface to allow sockets to work in the presence of stacked filesystems.
PR: 275871 Reviewed by: kib (prior version), olce Tested by: Karlo Miličević <karlo98.m@gmail.com> MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D44288
show more ...
|
#
6c8ded00 |
| 02-Jan-2024 |
Jason A. Harmening <jah@FreeBSD.org> |
unionfs: accommodate underlying FS calls that may re-lock
Since non-doomed unionfs vnodes always share their primary lock with either the lower or upper vnode, any forwarded call to the base FS whic
unionfs: accommodate underlying FS calls that may re-lock
Since non-doomed unionfs vnodes always share their primary lock with either the lower or upper vnode, any forwarded call to the base FS which transiently drops that upper or lower vnode lock may result in the unionfs vnode becoming completely unlocked during that transient window. The unionfs vnode may then become doomed by a concurrent forced unmount, which can lead to either or both of the following:
--Complete loss of the unionfs lock: in the process of being doomed, the unionfs vnode switches back to the default vnode lock, so even if the base FS VOP reacquires the upper/lower vnode lock, that no longer translates into the unionfs vnode being relocked. This will then violate that caller's locking assumptions as well as various assertions that are enabled with DEBUG_VFS_LOCKS.
--Complete less of reference on the upper/lower vnode: the caller normally holds a reference on the unionfs vnode, while the unionfs vnode in turn holds references on the upper/lower vnodes. But in the course of being doomed, the unionfs vnode will drop the latter set of references, which can effectively lead to the base FS VOP executing with no references at all on its vnode, violating the assumption that vnodes can't be recycled during these calls and (if lucky) violating various assertions in the base FS.
Fix this by adding two new functions, unionfs_forward_vop_start_pair() and unionfs_forward_vop_finish_pair(), which are intended to bookend any forwarded VOP which may transiently unlock the relevant vnode(s). These functions are currently only applied to VOPs that modify file state (and require vnode reference and lock state to be identical at call entry and exit), as the common reason for transiently dropping locks is to update filesystem metadata.
Reviewed by: olce Tested by: pho MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D44076
show more ...
|
#
2656fc29 |
| 24-Dec-2023 |
Jason A. Harmening <jah@FreeBSD.org> |
unionfs: upgrade the vnode lock during fsync() if necessary
If the underlying upper FS supports shared locking for write ops, as is the case with ZFS, VOP_FSYNC() may only be called with the vnode l
unionfs: upgrade the vnode lock during fsync() if necessary
If the underlying upper FS supports shared locking for write ops, as is the case with ZFS, VOP_FSYNC() may only be called with the vnode lock held shared. In this case, temporarily upgrade the lock for those unionfs maintenance operations which require exclusive locking.
While here, make unionfs inherit the upper FS' support for shared write locking. Since the upper FS is the target of VOP_GETWRITEMOUNT() this is what will dictate the locking behavior of any unionfs caller that uses vn_start_write() + vn_lktype_write(), so unionfs must be prepared for the caller to only hold a shared vnode lock in these cases.
Found in local testing of unionfs atop ZFS with DEBUG_VFS_LOCKS.
MFC after: 2 weeks Reviewed by: kib, olce Differential Revision: https://reviews.freebsd.org/D43817
show more ...
|
#
cc3ec9f7 |
| 22-Dec-2023 |
Jason A. Harmening <jah@FreeBSD.org> |
unionfs: cache upper/lower mount objects
Store the upper/lower FS mount objects in unionfs per-mount data and use these instead of the v_mount field of the upper/lower root vnodes. As described in
unionfs: cache upper/lower mount objects
Store the upper/lower FS mount objects in unionfs per-mount data and use these instead of the v_mount field of the upper/lower root vnodes. As described in the referenced PR, it is unsafe to access this field on the unionfs unmount path as ZFS rollback may have obliterated the v_mount field of the upper or lower root vnode. Use these stored objects to slightly simplify other code that needs access to the upper/lower mount objects as well.
PR: 275870 Reported by: Karlo Miličević <karlo98.m@gmail.com> Tested by: Karlo Miličević <karlo98.m@gmail.com> Reviewed by: kib (prior version), olce MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D43815
show more ...
|
#
552581e7 |
| 03-Feb-2024 |
rilysh <nightquick@proton.me> |
sys/fs/unionfs/union_vnops.c: remove an extra semicolon
Signed-off-by: rilysh <nightquick@proton.me> Reviewed by: imp Pull Request: https://github.com/freebsd/freebsd-src/pull/959
|
#
29363fb4 |
| 23-Nov-2023 |
Warner Losh <imp@FreeBSD.org> |
sys: Remove ancient SCCS tags.
Remove ancient SCCS tags from the tree, automated scripting, with two minor fixup to keep things compiling. All the common forms in the tree were removed with a perl s
sys: Remove ancient SCCS tags.
Remove ancient SCCS tags from the tree, automated scripting, with two minor fixup to keep things compiling. All the common forms in the tree were removed with a perl script.
Sponsored by: Netflix
show more ...
|
Revision tags: release/14.0.0 |
|
#
2ff63af9 |
| 16-Aug-2023 |
Warner Losh <imp@FreeBSD.org> |
sys: Remove $FreeBSD$: one-line .h pattern
Remove /^\s*\*+\s*\$FreeBSD\$.*$\n/
|
Revision tags: release/13.2.0 |
|
#
93fe61af |
| 16-Jan-2023 |
Jason A. Harmening <jah@FreeBSD.org> |
unionfs_mkdir(): handle dvp reclamation
The underlying VOP_MKDIR() implementation may temporarily drop the parent directory vnode's lock. If the vnode is reclaimed during that window, the unionfs v
unionfs_mkdir(): handle dvp reclamation
The underlying VOP_MKDIR() implementation may temporarily drop the parent directory vnode's lock. If the vnode is reclaimed during that window, the unionfs vnode will effectively become unlocked because the its v_vnlock field will be reset. To uphold the locking requirements of VOP_MKDIR() and to avoid triggering various VFS assertions, explicitly re-lock the unionfs vnode before returning in this case.
Note that there are almost certainly other cases in which we'll similarly need to handle vnode relocking by the underlying FS; this is the only one that's caused problems in stress testing so far. A more general solution, such as that employed for nullfs in null_bypass(), will likely need to be implemented.
Tested by: pho Reviewed by: kib, markj Differential Revision: https://reviews.freebsd.org/D39272
show more ...
|
#
d711884e |
| 16-Jan-2023 |
Jason A. Harmening <jah@FreeBSD.org> |
Remove unionfs_islocked()
The implementation is racy; if the unionfs vnode is not in fact locked, vnode private data may be concurrently altered or freed. Instead, simply rely upon the standard impl
Remove unionfs_islocked()
The implementation is racy; if the unionfs vnode is not in fact locked, vnode private data may be concurrently altered or freed. Instead, simply rely upon the standard implementation to query the v_vnlock field, which is type-stable and will reflect the correct lower/upper vnode configuration for the unionfs node.
Tested by: pho Reviewed by: kib, markj Differential Revision: https://reviews.freebsd.org/D39272
show more ...
|
#
a5d82b55 |
| 16-Jan-2023 |
Jason A. Harmening <jah@FreeBSD.org> |
Remove an impossible condition from unionfs_lock()
We hold the vnode interlock, so vnode private data cannot suddenly become NULL.
Tested by: pho Reviewed by: kib, markj Differential Revision: http
Remove an impossible condition from unionfs_lock()
We hold the vnode interlock, so vnode private data cannot suddenly become NULL.
Tested by: pho Reviewed by: kib, markj Differential Revision: https://reviews.freebsd.org/D39272
show more ...
|
#
a18c403f |
| 16-Jan-2023 |
Jason A. Harmening <jah@FreeBSD.org> |
unionfs: remove LK_UPGRADE if falling back to the standard lock
The LK_UPGRADE operation may have temporarily dropped the upper or lower vnode's lock. If the unionfs vnode was reclaimed during that
unionfs: remove LK_UPGRADE if falling back to the standard lock
The LK_UPGRADE operation may have temporarily dropped the upper or lower vnode's lock. If the unionfs vnode was reclaimed during that window, its lock field will be reset to no longer point at the upper/lower vnode lock, so the lock operation will use the standard lock stored in v_lock. Remove LK_UPGRADE from the flags in this case to avoid a lockmgr assertion, as this lock has not been previously owned by the calling thread.
Reported by: pho Tested by: pho Reviewed by: kib, markj Differential Revision: https://reviews.freebsd.org/D39272
show more ...
|
Revision tags: release/12.4.0 |
|
#
5b5b7e2c |
| 17-Sep-2022 |
Mateusz Guzik <mjg@FreeBSD.org> |
vfs: always retain path buffer after lookup
This removes some of the complexity needed to maintain HASBUF and allows for removing injecting SAVENAME by filesystems.
Reviewed by: kib (previous versi
vfs: always retain path buffer after lookup
This removes some of the complexity needed to maintain HASBUF and allows for removing injecting SAVENAME by filesystems.
Reviewed by: kib (previous version) Differential Revision: https://reviews.freebsd.org/D36542
show more ...
|
Revision tags: release/13.1.0 |
|
#
ac9c3c32 |
| 14-Apr-2022 |
John Baldwin <jhb@FreeBSD.org> |
unionfs: Use __diagused for a variable only used in KASSERT().
|
#
fcb16474 |
| 15-Feb-2022 |
Jason A. Harmening <jah@FreeBSD.org> |
unionfs: rework unionfs_getwritemount()
VOP_GETWRITEMOUNT() is called on the vn_start_write() path without any vnode locks guaranteed to be held. It's therefore unsafe to blindly access per-mount a
unionfs: rework unionfs_getwritemount()
VOP_GETWRITEMOUNT() is called on the vn_start_write() path without any vnode locks guaranteed to be held. It's therefore unsafe to blindly access per-mount and per-vnode data. Instead, follow the approach taken by nullfs and use the vnode interlock coupled with the hold count to ensure the mount and the vnode won't be recycled while they are being accessed.
Reviewed by: kib (earlier version), markj, pho Tested by: pho Differential Revision: https://reviews.freebsd.org/D34282
show more ...
|
#
83d61d5b |
| 30-Jan-2022 |
Jason A. Harmening <jah@FreeBSD.org> |
unionfs: do not force LK_NOWAIT if VI_OWEINACT is set
I see no apparent need to avoid waiting on the lock just because vinactive() may be called on another thread while the thread that cleared the v
unionfs: do not force LK_NOWAIT if VI_OWEINACT is set
I see no apparent need to avoid waiting on the lock just because vinactive() may be called on another thread while the thread that cleared the vnode refcount has the lock dropped. In fact, this can at least lead to a panic of the form "vn_lock: error <errno> incompatible with flags" if LK_RETRY was passed to VOP_LOCK(). In this case LK_NOWAIT may cause the underlying FS to return an error which is incompatible with LK_RETRY.
Reported by: pho Reviewed by: kib, markj, pho Differential Revision: https://reviews.freebsd.org/D34109
show more ...
|
#
6ff167aa |
| 30-Jan-2022 |
Jason A. Harmening <jah@FreeBSD.org> |
unionfs: allow lock recursion when reclaiming the root vnode
The unionfs root vnode will always share a lock with its lower vnode. If unionfs was mounted with the 'below' option, this will also be t
unionfs: allow lock recursion when reclaiming the root vnode
The unionfs root vnode will always share a lock with its lower vnode. If unionfs was mounted with the 'below' option, this will also be the vnode covered by the unionfs mount. During unmount, the covered vnode will be locked by dounmount() while the unionfs root vnode will be locked by vgone(). This effectively requires recursion on the same underlying like, albeit through two different vnodes.
Reported by: pho Reviewed by: kib, markj, pho Differential Revision: https://reviews.freebsd.org/D34109
show more ...
|
#
0cd8f3e9 |
| 30-Jan-2022 |
Jason A. Harmening <jah@FreeBSD.org> |
unionfs: fix assertion order in unionfs_lock()
VOP_LOCK() may be handed a vnode that is concurrently reclaimed. unionfs_lock() accounts for this by checking for empty vnode private data under the in
unionfs: fix assertion order in unionfs_lock()
VOP_LOCK() may be handed a vnode that is concurrently reclaimed. unionfs_lock() accounts for this by checking for empty vnode private data under the interlock. But it incorrectly asserts that the vnode is using the unionfs dispatch table before making this check. Reverse the order, and also update KASSERT_UNIONFS_VNODE() to provide more useful information.
Reported by: pho Reviewed by: kib, markj, pho Differential Revision: https://reviews.freebsd.org/D34109
show more ...
|
#
a01ca46b |
| 17-Jan-2022 |
Jason A. Harmening <jah@FreeBSD.org> |
unionfs: use VV_ROOT to check for root vnode in unionfs_lock()
This avoids a potentially wild reference to the mount object. Additionally, simplify some of the checks around VV_ROOT in unionfs_nodeg
unionfs: use VV_ROOT to check for root vnode in unionfs_lock()
This avoids a potentially wild reference to the mount object. Additionally, simplify some of the checks around VV_ROOT in unionfs_nodeget().
Reviewed by: kib Differential Revision: https://reviews.freebsd.org/D33914
show more ...
|
#
39a2dc44 |
| 03-Jan-2022 |
Jason A. Harmening <jah@FreeBSD.org> |
unionfs: allow vnode lock to be held shared during VOP_OPEN
do_execve() will hold the vnode lock shared when it calls VOP_OPEN(), but unionfs_open() requires the lock to be held exclusive to correct
unionfs: allow vnode lock to be held shared during VOP_OPEN
do_execve() will hold the vnode lock shared when it calls VOP_OPEN(), but unionfs_open() requires the lock to be held exclusive to correctly synchronize node status updates. This requirement is asserted in unionfs_get_node_status().
Change unionfs_open() to temporarily upgrade the lock as is already done in unionfs_close(). Related to this, fix various cases throughout unionfs in which vnodes are not checked for reclamation following lock upgrades that may have temporarily dropped the lock. Also fix another related issue in which unionfs_lock() can incorrectly add LK_NOWAIT during a downgrade operation, which trips a lockmgr assertion.
Reviewed by: kib (prior version), markj, pho Reported by: pho Differential Revision: https://reviews.freebsd.org/D33729
show more ...
|
#
9e891d43 |
| 22-Dec-2021 |
Jason A. Harmening <jah@FreeBSD.org> |
unionfs: implement VOP_SET_TEXT/VOP_UNSET_TEXT
The implementation simply passes the text ref to the appropriate underlying vnode. Without this, the default [un]set_text implementation will only man
unionfs: implement VOP_SET_TEXT/VOP_UNSET_TEXT
The implementation simply passes the text ref to the appropriate underlying vnode. Without this, the default [un]set_text implementation will only manage the text ref on the unionfs vnode, causing it to be out of sync with the underlying filesystems and potentially allowing corruption of executable file contents. On INVARIANTS kernels, it also readily produces a panic on process termination because the VM object representing the executable mapping is backed by the underlying vnode, not the unionfs vnode.
PR: 251342 Reviewed by: kib Differential Revision: https://reviews.freebsd.org/D33611
show more ...
|