[Bug 251363] use unionfs as a disk-cache for NFS [feature]
bugzilla-noreply at freebsd.org
bugzilla-noreply at freebsd.org
Thu Nov 26 01:01:49 UTC 2020
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=251363
--- Comment #6 from Gunther Schadow <raj at gusw.net> ---
Success! Here is my full diff in /usr/src/sys/fs/unionfs
# svnlite diff -x-w
Index: union.h
===================================================================
--- union.h (revision 368012)
+++ union.h (working copy)
@@ -40,6 +40,12 @@
#ifdef _KERNEL
+/* copy policy from lower to upper layer */
+typedef enum _unionfs_copypolicy {
+ UNIONFS_COPY_ON_WRITE = 0,
+ UNIONFS_COPY_ALWAYS
+} unionfs_copypolicy;
+
/* copy method of attr from lower to upper */
typedef enum _unionfs_copymode {
UNIONFS_TRADITIONAL = 0,
@@ -57,6 +63,7 @@
struct vnode *um_lowervp; /* VREFed once */
struct vnode *um_uppervp; /* VREFed once */
struct vnode *um_rootvp; /* ROOT vnode */
+ unionfs_copypolicy um_copypolicy;
unionfs_copymode um_copymode;
unionfs_whitemode um_whitemode;
uid_t um_uid;
Index: union_vfsops.c
===================================================================
--- union_vfsops.c (revision 368012)
+++ union_vfsops.c (working copy)
@@ -89,6 +89,7 @@
gid_t gid;
u_short udir;
u_short ufile;
+ unionfs_copypolicy copypolicy;
unionfs_copymode copymode;
unionfs_whitemode whitemode;
struct nameidata nd, *ndp;
@@ -102,6 +103,7 @@
gid = 0;
udir = 0;
ufile = 0;
+ copypolicy = UNIONFS_COPY_ON_WRITE;
copymode = UNIONFS_TRANSPARENT; /* default */
whitemode = UNIONFS_WHITE_ALWAYS;
ndp = &nd;
@@ -190,6 +192,20 @@
return (EINVAL);
}
}
+ if (vfs_getopt(mp->mnt_optnew, "copypolicy", (void **)&tmp,
+ NULL) == 0) {
+ if (tmp == NULL) {
+ vfs_mount_error(mp, "Invalid copy policy");
+ return (EINVAL);
+ } else if (strcasecmp(tmp, "always") == 0)
+ copypolicy = UNIONFS_COPY_ALWAYS;
+ else if (strcasecmp(tmp, "onwrite") == 0)
+ copypolicy = UNIONFS_COPY_ON_WRITE;
+ else {
+ vfs_mount_error(mp, "Invalid copy policy");
+ return (EINVAL);
+ }
+ }
if (vfs_getopt(mp->mnt_optnew, "copymode", (void **)&tmp,
NULL) == 0) {
if (tmp == NULL) {
@@ -229,7 +245,7 @@
UNIONFSDEBUG("unionfs_mount: uid=%d, gid=%d\n", uid, gid);
UNIONFSDEBUG("unionfs_mount: udir=0%03o, ufile=0%03o\n", udir, ufile);
- UNIONFSDEBUG("unionfs_mount: copymode=%d\n", copymode);
+ UNIONFSDEBUG("unionfs_mount: copypolicy=%d, copymode=%d,
whitemode=%d\n", copypolicy, copymode, whitemode);
/*
* Find upper node
@@ -265,6 +281,7 @@
ump->um_gid = gid;
ump->um_udir = udir;
ump->um_ufile = ufile;
+ ump->um_copypolicy = copypolicy;
ump->um_copymode = copymode;
ump->um_whitemode = whitemode;
Index: union_vnops.c
===================================================================
--- union_vnops.c (revision 368012)
+++ union_vnops.c (working copy)
@@ -464,6 +464,7 @@
{
int error;
struct unionfs_node *unp;
+ struct unionfs_mount *ump;
struct unionfs_node_status *unsp;
struct vnode *uvp;
struct vnode *lvp;
@@ -477,6 +478,7 @@
error = 0;
unp = VTOUNIONFS(ap->a_vp);
+ ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount);
uvp = unp->un_uppervp;
lvp = unp->un_lowervp;
targetvp = NULLVP;
@@ -498,7 +500,7 @@
}
if (targetvp == NULLVP) {
if (uvp == NULLVP) {
- if ((ap->a_mode & FWRITE) && lvp->v_type == VREG) {
+ if (((ap->a_mode & FWRITE) || (ump->um_copypolicy ==
UNIONFS_COPY_ALWAYS)) && lvp->v_type == VREG) {
error = unionfs_copyfile(unp,
!(ap->a_mode & O_TRUNC), cred, td);
if (error != 0)
r
Testing:
# mdconfig -a -t vnode /data/cachfs
md0
newfs /dev/md0
/dev/md0: 1024.0MB (2097152 sectors) block size 32768, fragment size 4096
using 4 cylinder groups of 256.03MB, 8193 blks, 32896 inodes.
super-block backups (for fsck_ffs -b #) at:
192, 524544, 1048896, 1573248
# mkdir /cache
# mount /dev/md0 /cache
# mount_unionfs -o copypolicy=always /cache /worker-efs
# /efs/bin/less
...
# /efs/local/bin/python3.7
...
# find /cache
cache
cache/.snap
cache/bin
cache/bin/less
cache/sbin
cache/local
cache/local/bin
cache/local/bin/python3.7
cache/local/lib
cache/local/lib/python3.7
cache/local/lib/python3.7/lib-dynload
cache/local/lib/python3.7/lib-dynload/readline.so
cache/local/lib/python3.7/encodings
cache/local/lib/python3.7/encodings/__pycache__
cache/local/lib/python3.7/encodings/__pycache__/__init__.cpython-37.pyc
cache/local/lib/python3.7/encodings/__pycache__/aliases.cpython-37.pyc
cache/local/lib/python3.7/encodings/__pycache__/utf_8.cpython-37.pyc
cache/local/lib/python3.7/encodings/__pycache__/latin_1.cpython-37.pyc
cache/local/lib/python3.7/__pycache__
cache/local/lib/python3.7/__pycache__/codecs.cpython-37.pyc
cache/local/lib/python3.7/__pycache__/io.cpython-37.pyc
cache/local/lib/python3.7/__pycache__/abc.cpython-37.pyc
cache/local/lib/python3.7/__pycache__/site.cpython-37.pyc
cache/local/lib/python3.7/__pycache__/os.cpython-37.pyc
cache/local/lib/python3.7/__pycache__/stat.cpython-37.pyc
cache/local/lib/python3.7/__pycache__/_collections_abc.cpython-37.pyc
cache/local/lib/python3.7/__pycache__/posixpath.cpython-37.pyc
cache/local/lib/python3.7/__pycache__/genericpath.cpython-37.pyc
cache/local/lib/python3.7/__pycache__/_sitebuiltins.cpython-37.pyc
cache/local/lib/python3.7/__pycache__/_bootlocale.cpython-37.pyc
cache/local/lib/python3.7/__pycache__/rlcompleter.cpython-37.pyc
cache/local/lib/python3.7/site-packages
cache/local/lib/python3.7/site-packages/easy-install.pth
...
So this is really cool, I can even evict the cache by just writing to the
unionfs!
This is nice, so I might not even need that UNIONFS_WIHTE_NEVER.
--
You are receiving this mail because:
You are the assignee for the bug.
More information about the freebsd-bugs
mailing list