https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=251363

--- Comment #9 from Gunther Schadow <r...@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.
_______________________________________________
freebsd-bugs@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"

Reply via email to