Skip to content

Commit

Permalink
Fix for hard link creation errors on unionfs.
Browse files Browse the repository at this point in the history
Since the commit [1] fusefs checks if the inodes of the source and the target
file are identical when creating a hard link. If they differ, an error is
returned. This, however, is a problem when using unionfs. Since hard links
across different file systems are not possible, unionfs copies the source file
from the r/o directory to the writeable directory first, and then creates the
hard link there.

* Install a fusefs2 kernel module which is identical to fusefs except for the
inode check.
* Let /etc/rc.d/mount_uzip unload fusefs if loaded, then load fusefs2.

1. https://cgit.freebsd.org/src/commit/sys/fs/fuse/fuse_vnops.c?h=stable/14&id=0bef4927ea858bb18b6f679bc0a36cff264dc842
  • Loading branch information
mrclksr committed Feb 7, 2024
1 parent 6a6847f commit 1de2e21
Show file tree
Hide file tree
Showing 20 changed files with 11,327 additions and 2 deletions.
23 changes: 23 additions & 0 deletions build
Expand Up @@ -45,6 +45,8 @@
#
# image Build the NomadBSD image.
#
# modules Build and install kernel modules from the "modules" directory
#
# ports Build and install all ports defined in build.cfg
#
# pkgs Install all packages from pkg.list
Expand Down Expand Up @@ -104,6 +106,7 @@ BUILD_DEPENCIES_LIST_EOF
)

BUILD_STAGES=$(cat << BUILD_STAGES_END
build_modules
install_packages
install_from_git_repos
build_setupgui
Expand Down Expand Up @@ -1158,6 +1161,25 @@ build_nomadbsd_update()
umount_chroot_devfs
}

build_and_install_kmod()
{
chroot "${SYSDIR}" sh -c \
"cd $1 && make clean; make && make install" || \
bail "Failed to install kernel module $1"
}

build_modules()
{
local MODULES_DIR="/usr/src/sys/modules"

for m in modules/*; do
[ "$m" = "." -o "$m" = ".." -o ! -d "$m" ] && continue
cp -a "$m" "${SYSDIR}/${MODULES_DIR}/" || bail
mod=$(basename "$m")
build_and_install_kmod "${MODULES_DIR}/${mod}"
done
}

install_nomadbsd_reset()
{
local make_opts=""
Expand Down Expand Up @@ -1433,6 +1455,7 @@ while [ $# -gt 0 ]; do
addusergui) build_addusergui;;
dmconfig) build_dmconfig;;
chusr) build_chusr;;
modules) build_modules;;
nbsdupdate) build_nomadbsd_update;;
reset) install_nomadbsd_reset;;
src) install_src_dist;;
Expand Down
2 changes: 2 additions & 0 deletions build.hlp
Expand Up @@ -27,6 +27,8 @@ installgui (Re)build and (re)install nomadbsd-install-gui

kernel Build a custom kernel using kernel/NOMADBSD

modules Build and install kernel modules from the "modules" directory

nbsdupdate Install nomadbsd-update.

pkgcfg Set up configuration files and users required by installed
Expand Down
5 changes: 3 additions & 2 deletions config/etc/rc.d/mount_uzip
Expand Up @@ -102,8 +102,9 @@ do_mount_unionfs()
fi
[ ! -d "${rwdir}" ] && mkdir -p "${rwdir}"
fi
if (! kldstat -q -m fusefs && ! kldstat -q -m fuse); then
kldload fusefs 2>/dev/null || kldload fuse 2>/dev/null
kldstat -q -n fusefs && kldunload fusefs
if (! kldstat -q -n fusefs2 && ! kldstat -q -n fusefs); then
kldload fusefs2 2>/dev/null || kldload fusefs 2>/dev/null
fi
unionfs -o cow,max_files=${unionfs_maxfiles} \
-o allow_other,use_ino,suid,nonempty,kernel_cache \
Expand Down
7 changes: 7 additions & 0 deletions modules/fusefs2/Makefile
@@ -0,0 +1,7 @@
.PATH: ${SRCTOP}/sys/modules/fusefs2
KMOD= fusefs2
SRCS= vnode_if.h \
fuse_node.c fuse_io.c fuse_device.c fuse_ipc.c fuse_file.c \
fuse_vfsops.c fuse_vnops.c fuse_internal.c fuse_main.c

.include <bsd.kmod.mk>
95 changes: 95 additions & 0 deletions modules/fusefs2/fuse.h
@@ -0,0 +1,95 @@
/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2007-2009 Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Copyright (C) 2005 Csaba Henk.
* All rights reserved.
*
* Copyright (c) 2019 The FreeBSD Foundation
*
* Portions of this software were developed by BFF Storage Systems, LLC under
* sponsorship from the FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

#include "fuse_kernel.h"

#define FUSE_DEFAULT_DAEMON_TIMEOUT 60 /* s */
#define FUSE_MIN_DAEMON_TIMEOUT 0 /* s */
#define FUSE_MAX_DAEMON_TIMEOUT 600 /* s */

/* misc */

SYSCTL_DECL(_vfs_fusefs);
SYSCTL_DECL(_vfs_fusefs_stats);

/* Fuse locking */

extern struct mtx fuse_mtx;
#define FUSE_LOCK() fuse_lck_mtx_lock(fuse_mtx)
#define FUSE_UNLOCK() fuse_lck_mtx_unlock(fuse_mtx)

#define RECTIFY_TDCR(td, cred) \
do { \
if (! (td)) \
(td) = curthread; \
if (! (cred)) \
(cred) = (td)->td_ucred; \
} while (0)

#define fuse_lck_mtx_lock(mtx) mtx_lock(&(mtx))
#define fuse_lck_mtx_unlock(mtx) mtx_unlock(&(mtx))

void fuse_ipc_init(void);
void fuse_ipc_destroy(void);

int fuse_device_init(void);
void fuse_device_destroy(void);

0 comments on commit 1de2e21

Please sign in to comment.