Date: Thu, 26 Nov 2020 02:50:15 +0000 From: bugzilla-noreply@freebsd.org To: bugs@FreeBSD.org Subject: [Bug 251363] use unionfs as a disk-cache for NFS [feature] Message-ID: <bug-251363-227-x6ZL2ISRyF@https.bugs.freebsd.org/bugzilla/> In-Reply-To: <bug-251363-227@https.bugs.freebsd.org/bugzilla/>
index | next in thread | previous in thread | raw e-mail
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=251363 --- Comment #9 from Gunther Schadow <raj@gusw.net> --- For completeness sake, I updated the mount_unionfs.8 man file also. Full diff out of /usr/src with svnlite diff -x-w: Index: sbin/mount_unionfs/mount_unionfs.8 =================================================================== --- sbin/mount_unionfs/mount_unionfs.8 (revision 368012) +++ sbin/mount_unionfs/mount_unionfs.8 (working copy) @@ -83,6 +83,16 @@ However, .Ar uniondir remains the mount point. +.It Cm copypolicy No = Cm onwrite | always +The normal behavior is copy-on-write with +.Cm onwrite +this is the standaed unionfs behavior. If +.Cm always +is spefied, then the a copy is made on the upper layer even if the +file or directory is accessed only for reading. This effectively +turns the upper layer into a cache which is an easy way to implement +a disk cache over an NFS filesystem, speeding up all subsequent accesses, +very useful for network booted systems. .It Cm copymode No = Cm traditional | transparent | masquerade Specifies the way to create a file or a directory in the upper layer automatically when needed. Index: sys/fs/unionfs/union.h =================================================================== --- sys/fs/unionfs/union.h (revision 368012) +++ sys/fs/unionfs/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: sys/fs/unionfs/union_vfsops.c =================================================================== --- sys/fs/unionfs/union_vfsops.c (revision 368012) +++ sys/fs/unionfs/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: sys/fs/unionfs/union_vnops.c =================================================================== --- sys/fs/unionfs/union_vnops.c (revision 368012) +++ sys/fs/unionfs/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 -- You are receiving this mail because: You are the assignee for the bug.home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-251363-227-x6ZL2ISRyF>
