Module Name:    src
Committed By:   dholland
Date:           Tue Jun 29 22:38:46 UTC 2021

Modified Files:
        src/sys/fs/union: union_vnops.c
        src/sys/fs/unionfs: unionfs_vnops.c

Log Message:
Onionfs needs to know about parsepath too, in case it has one of the
other cases underneath it.

The solution here is not really very good (take the longer
path-to-consume if they're different) but it will serve for the cases
that exist.

(If we were to add a fs that really uses different naming semantics,
we'd have to take additional steps; probably it doesn't make sense to
allow unionfs to union such a thing with a normal fs and attempting it
should fail at mount time.)

Update fs/unionfs as well to avoid increasing the current set of
compile failures there. Though maybe it's time to just remove
fs/unionfs.


To generate a diff of this commit:
cvs rdiff -u -r1.75 -r1.76 src/sys/fs/union/union_vnops.c
cvs rdiff -u -r1.15 -r1.16 src/sys/fs/unionfs/unionfs_vnops.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/fs/union/union_vnops.c
diff -u src/sys/fs/union/union_vnops.c:1.75 src/sys/fs/union/union_vnops.c:1.76
--- src/sys/fs/union/union_vnops.c:1.75	Tue Jun 29 22:34:07 2021
+++ src/sys/fs/union/union_vnops.c	Tue Jun 29 22:38:46 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: union_vnops.c,v 1.75 2021/06/29 22:34:07 dholland Exp $	*/
+/*	$NetBSD: union_vnops.c,v 1.76 2021/06/29 22:38:46 dholland Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993, 1994, 1995
@@ -72,7 +72,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.75 2021/06/29 22:34:07 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.76 2021/06/29 22:38:46 dholland Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -93,6 +93,7 @@ __KERNEL_RCSID(0, "$NetBSD: union_vnops.
 #include <miscfs/genfs/genfs.h>
 #include <miscfs/specfs/specdev.h>
 
+int union_parsepath(void *);
 int union_lookup(void *);
 int union_create(void *);
 int union_whiteout(void *);
@@ -144,7 +145,7 @@ static int union_lookup1(struct vnode *,
 int (**union_vnodeop_p)(void *);
 const struct vnodeopv_entry_desc union_vnodeop_entries[] = {
 	{ &vop_default_desc, vn_default_error },
-	{ &vop_parsepath_desc, genfs_parsepath },	/* parsepath */
+	{ &vop_parsepath_desc, union_parsepath },	/* parsepath */
 	{ &vop_lookup_desc, union_lookup },		/* lookup */
 	{ &vop_create_desc, union_create },		/* create */
 	{ &vop_whiteout_desc, union_whiteout },		/* whiteout */
@@ -197,6 +198,40 @@ const struct vnodeopv_desc union_vnodeop
 	((vp)->v_type == VBLK || (vp)->v_type == VCHR || \
 	(vp)->v_type == VSOCK || (vp)->v_type == VFIFO)
 
+int
+union_parsepath(void *v)
+{
+	struct vop_parsepath_args /* {
+		struct vnode *a_dvp;
+		const char *a_name;
+		size_t *a_retval;
+	} */ *ap = v;
+	struct vnode *upperdvp, *lowerdvp;
+	size_t upper, lower;
+	int error;
+
+	upperdvp = UPPERVP(ap->a_dvp);
+	lowerdvp = LOWERVP(ap->a_dvp);
+
+	error = VOP_PARSEPATH(upperdvp, ap->a_name, &upper);
+	if (error) {
+		return error;
+	}
+
+	error = VOP_PARSEPATH(lowerdvp, ap->a_name, &lower);
+	if (error) {
+		return error;
+	}
+
+	/*
+	 * If they're different, use the larger one. This is not a
+	 * comprehensive solution, but it's sufficient for the
+	 * non-default cases of parsepath that currently exist.
+	 */
+	*ap->a_retval = MAX(upper, lower);
+	return 0;
+}
+
 static int
 union_lookup1(struct vnode *udvp, struct vnode **dvpp, struct vnode **vpp,
 	struct componentname *cnp)

Index: src/sys/fs/unionfs/unionfs_vnops.c
diff -u src/sys/fs/unionfs/unionfs_vnops.c:1.15 src/sys/fs/unionfs/unionfs_vnops.c:1.16
--- src/sys/fs/unionfs/unionfs_vnops.c:1.15	Tue Jun 29 22:34:08 2021
+++ src/sys/fs/unionfs/unionfs_vnops.c	Tue Jun 29 22:38:46 2021
@@ -65,6 +65,42 @@
 #endif
 
 static int
+unionfs_parsepath(void *v)
+{
+	struct vop_parsepath_args /* {
+		struct vnode *a_dvp;
+		const char *a_name;
+		size_t *a_retval;
+	} */ *ap = v;
+	struct unionfs_node *dunp;
+	struct vnode *upperdvp, *lowerdvp;
+	size_t upper, lower;
+	int error;
+
+	dunp = VTOUNIONFS(ap->a_dvp);
+	upperdvp = dunp->un_uppervp;
+	lowerdvp = dunp->un_lowervp;
+
+	error = VOP_PARSEPATH(upperdvp, ap->a_name, &upper);
+	if (error) {
+		return error;
+	}
+
+	error = VOP_PARSEPATH(lowerdvp, ap->a_name, &lower);
+	if (error) {
+		return error;
+	}
+
+	/*
+	 * If they're different, use the larger one. This is not a
+	 * comprehensive solution, but it's sufficient for the
+	 * non-default cases of parsepath that currently exist.
+	 */
+	*ap->a_retval = MAX(upper, lower);
+	return 0;
+}
+
+static int
 unionfs_lookup(void *v)
 {
 	struct vop_lookup_args *ap = v;
@@ -1814,7 +1850,7 @@ unionfs_revoke(void *v)
 int (**unionfs_vnodeop_p)(void *);
 const struct vnodeopv_entry_desc unionfs_vnodeop_entries[] = {
 	{ &vop_default_desc, vn_default_error },
-	{ &vop_parsepath_desc, genfs_parsepath },	/* parsepath */
+	{ &vop_parsepath_desc, unionfs_parsepath },	/* parsepath */
 	{ &vop_lookup_desc, unionfs_lookup },		/* lookup */
 	{ &vop_create_desc, unionfs_create },		/* create */
 	{ &vop_whiteout_desc, unionfs_whiteout },	/* whiteout */

Reply via email to