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 */