Module Name:    src
Committed By:   dholland
Date:           Tue Jun 29 22:37:50 UTC 2021

Modified Files:
        src/sys/fs/hfs: hfs_vnops.c

Log Message:
Implement VOP_PARSEPATH() for hfs.

This checks for a following "/rsrc" at the end of the pathname (to
indicate the resource fork of a file) and assimilates it into the
component name to be looked up. Then cn_namelen will already include
this text in lookup, and it's no longer necessary to muck with
cn_consume.

Invalid uses of "/rsrc" are ignored rather than rejected, which
appears to be the same as the old behavior. It is possible that the
parsepath logic should only consume the "/rsrc" if the name names a
file and not a directory, which would require looking it up in
parsepath and be a general nuisance; I hope not. It's also possible
that the whole thing doesn't work at all now, or it didn't before, as
I don't have any way to test it.


To generate a diff of this commit:
cvs rdiff -u -r1.37 -r1.38 src/sys/fs/hfs/hfs_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/hfs/hfs_vnops.c
diff -u src/sys/fs/hfs/hfs_vnops.c:1.37 src/sys/fs/hfs/hfs_vnops.c:1.38
--- src/sys/fs/hfs/hfs_vnops.c:1.37	Tue Jun 29 22:34:06 2021
+++ src/sys/fs/hfs/hfs_vnops.c	Tue Jun 29 22:37:50 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: hfs_vnops.c,v 1.37 2021/06/29 22:34:06 dholland Exp $	*/
+/*	$NetBSD: hfs_vnops.c,v 1.38 2021/06/29 22:37:50 dholland Exp $	*/
 
 /*-
  * Copyright (c) 2005, 2007 The NetBSD Foundation, Inc.
@@ -101,7 +101,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hfs_vnops.c,v 1.37 2021/06/29 22:34:06 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hfs_vnops.c,v 1.38 2021/06/29 22:37:50 dholland Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ipsec.h"
@@ -132,6 +132,7 @@ __KERNEL_RCSID(0, "$NetBSD: hfs_vnops.c,
 
 #include <miscfs/genfs/genfs.h>
 
+int	hfs_vop_parsepath(void *);
 int	hfs_vop_lookup(void *);
 int	hfs_vop_open(void *);
 int	hfs_vop_close(void *);
@@ -331,6 +332,29 @@ const struct vnodeopv_desc hfs_fifoop_op
 	{ &hfs_fifoop_p, hfs_fifoop_entries };
 
 int
+hfs_vop_parsepath(void *v)
+{
+	struct vop_parsepath_args /* {
+		struct vnode *a_dvp;
+		const char *a_name;
+		size_t *a_retval;
+	} */ *ap = v;
+	size_t len;
+	int error;
+
+	error = genfs_parsepath(v);
+	if (error) {
+		return error;
+	}
+
+	len = *ap->a_retval;
+	if (!strcmp(ap->a_name + len, "/rsrc")) {
+		*ap->a_retval += 5;
+	}
+	return 0;
+}
+
+int
 hfs_vop_lookup(void *v)
 {
 	struct vop_lookup_v2_args /* {
@@ -346,6 +370,8 @@ hfs_vop_lookup(void *v)
 	struct vnode *vdp;		/* vnode for directory being searched */
 	hfs_catalog_key_t key;	/* hfs+ catalog search key for requested child */
 	hfs_catalog_keyed_record_t rec; /* catalog record of requested child */
+	size_t namelen;
+	int use_resource_fork = 0;
 	unichar_t* unicn;		/* name of component, in Unicode */
 	const char *pname;
 	int error;
@@ -420,12 +446,18 @@ hfs_vop_lookup(void *v)
 
 		hfslib_init_cbargs(&cbargs);
 
+		namelen = cnp->cn_namelen;
+		if (namelen > 5 &&
+		    !strcmp(cnp->cn_nameptr + namelen - 5, "/rsrc")) {
+			namelen -= 5;
+			use_resource_fork = 1;
+		}
+
 		/* XXX: when decomposing, string could grow
 		   and we have to handle overflow */
-		unicn = malloc(cnp->cn_namelen * sizeof(unicn[0]),
-		    M_TEMP, M_WAITOK);
-		len = utf8_to_utf16(unicn, cnp->cn_namelen,
-		    cnp->cn_nameptr, cnp->cn_namelen, 0, NULL);
+		unicn = malloc(namelen * sizeof(unicn[0]), M_TEMP, M_WAITOK);
+		len = utf8_to_utf16(unicn, namelen,
+		    cnp->cn_nameptr, namelen, 0, NULL);
 		for (ni = 0; ni < len; ni++)
 			if (unicn[ni] == (unichar_t)':')
 				unicn[ni] = (unichar_t)'/';
@@ -462,13 +494,11 @@ hfs_vop_lookup(void *v)
 		}
 
 		if (rec.type == HFS_REC_FILE
-		    && strcmp(cnp->cn_nameptr+cnp->cn_namelen, "/rsrc") == 0
+		    && use_resource_fork
 		    && rec.file.rsrc_fork.logical_size > 0) {
-		    /* advance namei next pointer to end of stirng */
-		    cnp->cn_consume = 5;
-		    cnp->cn_flags &= ~REQUIREDIR; /* XXX: needed? */
-		    error = hfs_vget_internal(vdp->v_mount, rec.file.cnid,
-			HFS_RSRCFORK, &tdp);
+		    /* advance namei next pointer to end of string */
+			error = hfs_vget_internal(vdp->v_mount, rec.file.cnid,
+			    HFS_RSRCFORK, &tdp);
 		} else
 			error = hfs_vget_internal(vdp->v_mount, rec.file.cnid,
 			    HFS_DATAFORK, &tdp);

Reply via email to