From 6adc52306ad41aacb0f80da53955e922601c7140 Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Tue, 21 Sep 2010 16:49:02 +0000 Subject: [PATCH] Modify devfs_fqpn() for future use in devfs path reference counting code: - Accept devfs_mount and devfs_dirent as the arguments instead of a vnode. This generalizes the function so that it can be used from contexts where vnode references are not available. - Accept NULL cnp argument. No '/' will be appended, if a NULL cnp is provided. - Make the function global and add its prototype to devfs.h. Reviewed by: kib --- sys/fs/devfs/devfs.h | 4 ++++ sys/fs/devfs/devfs_vnops.c | 33 +++++++++++++++++++-------------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/sys/fs/devfs/devfs.h b/sys/fs/devfs/devfs.h index 87549d222b06..433fa0d96030 100644 --- a/sys/fs/devfs/devfs.h +++ b/sys/fs/devfs/devfs.h @@ -122,6 +122,8 @@ struct devfs_rule { MALLOC_DECLARE(M_DEVFS); #endif +struct componentname; + struct devfs_dirent { struct cdev_priv *de_cdp; int de_inode; @@ -178,6 +180,8 @@ void devfs_rules_cleanup (struct devfs_mount *dm); int devfs_rules_ioctl(struct devfs_mount *dm, u_long cmd, caddr_t data, struct thread *td); int devfs_allocv(struct devfs_dirent *de, struct mount *mp, int lockmode, struct vnode **vpp); +char *devfs_fqpn(char *, struct devfs_mount *, struct devfs_dirent *, + struct componentname *); void devfs_delete(struct devfs_mount *dm, struct devfs_dirent *de, int flags); void devfs_dirent_free(struct devfs_dirent *de); void devfs_populate (struct devfs_mount *dm); diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c index 2c27b7d8357e..bbf068003076 100644 --- a/sys/fs/devfs/devfs_vnops.c +++ b/sys/fs/devfs/devfs_vnops.c @@ -299,29 +299,34 @@ finished: } /* - * Construct the fully qualified path name relative to the mountpoint + * Construct the fully qualified path name relative to the mountpoint. + * If a NULL cnp is provided, no '/' is appended to the resulting path. */ -static char * -devfs_fqpn(char *buf, struct vnode *dvp, struct componentname *cnp) +char * +devfs_fqpn(char *buf, struct devfs_mount *dmp, struct devfs_dirent *dd, + struct componentname *cnp) { int i; - struct devfs_dirent *de, *dd; - struct devfs_mount *dmp; + struct devfs_dirent *de; + + sx_assert(&dmp->dm_lock, SA_LOCKED); - dmp = VFSTODEVFS(dvp->v_mount); - dd = dvp->v_data; i = SPECNAMELEN; buf[i] = '\0'; - i -= cnp->cn_namelen; + if (cnp != NULL) + i -= cnp->cn_namelen; if (i < 0) return (NULL); - bcopy(cnp->cn_nameptr, buf + i, cnp->cn_namelen); + if (cnp != NULL) + bcopy(cnp->cn_nameptr, buf + i, cnp->cn_namelen); de = dd; while (de != dmp->dm_rootdir) { - i--; - if (i < 0) - return (NULL); - buf[i] = '/'; + if (cnp != NULL || i < SPECNAMELEN) { + i--; + if (i < 0) + return (NULL); + buf[i] = '/'; + } i -= de->de_dirent->d_namlen; if (i < 0) return (NULL); @@ -878,7 +883,7 @@ devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlock) * OK, we didn't have an entry for the name we were asked for * so we try to see if anybody can create it on demand. */ - pname = devfs_fqpn(specname, dvp, cnp); + pname = devfs_fqpn(specname, dmp, dd, cnp); if (pname == NULL) break;