#include <sys/vnode_internal.h>
#include <stdarg.h>
#include <libkern/OSAtomic.h>
+#include <os/refcnt.h>
#define BSD_KERNEL_PRIVATE 1 /* devfs_make_link() prototype */
#include "devfs.h"
#include "devfsdefs.h"
lck_mtx_t devfs_mutex;
lck_mtx_t devfs_attr_mutex;
+os_refgrp_decl(static, devfs_refgrp, "devfs", NULL);
+
devdirent_t * dev_root = NULL; /* root of backing tree */
struct devfs_stats devfs_stats; /* hold stats */
return ENOTSUP;
}
#ifdef HIDDEN_MOUNTPOINT
- MALLOC(devfs_hidden_mount, struct mount *, sizeof(struct mount),
- M_MOUNT, M_WAITOK);
- bzero(devfs_hidden_mount, sizeof(struct mount));
+ devfs_hidden_mount = zalloc_flags(mount_zone, Z_WAITOK | Z_ZERO);
mount_lock_init(devfs_hidden_mount);
TAILQ_INIT(&devfs_hidden_mount->mnt_vnodelist);
TAILQ_INIT(&devfs_hidden_mount->mnt_workerqueue);
= (struct devfsmount *)devfs_hidden_mount->mnt_data;
#endif /* HIDDEN_MOUNTPOINT */
#if CONFIG_MACF
- mac_devfs_label_associate_directory("/", strlen("/"),
+ mac_devfs_label_associate_directory("/", (int) strlen("/"),
dev_root->de_dnp, "/");
#endif
devfs_ready = 1;
#if CONFIG_MACF
mac_devfs_label_associate_directory(
dirnode->dn_typeinfo.Dir.myname->de_name,
- strlen(dirnode->dn_typeinfo.Dir.myname->de_name),
+ (int) strlen(dirnode->dn_typeinfo.Dir.myname->de_name),
dnp, fullpath);
#endif
devfs_propogate(dirnode->dn_typeinfo.Dir.myname, dirent_p, delp);
devnode_t * *dn_pp, struct devfsmount *dvm)
{
devnode_t * dnp = NULL;
+ int error = 0;
#if defined SPLIT_DEVS
/*
#endif
}
dnp->dn_dvm = dvm;
- dnp->dn_refcount = 0;
+
+ /* Note: this inits the reference count to 1, this is considered unreferenced */
+ os_ref_init_raw(&dnp->dn_refcount, &devfs_refgrp);
dnp->dn_ino = devfs_unique_fileno;
devfs_unique_fileno++;
typeinfo->Slnk.namelen + 1,
M_DEVFSNODE, M_WAITOK);
if (!dnp->dn_typeinfo.Slnk.name) {
- FREE(dnp, M_DEVFSNODE);
- return ENOMEM;
+ error = ENOMEM;
+ break;
}
strlcpy(dnp->dn_typeinfo.Slnk.name, typeinfo->Slnk.name,
typeinfo->Slnk.namelen + 1);
#endif /* FDESC */
default:
- return EINVAL;
+ error = EINVAL;
}
- *dn_pp = dnp;
- DEVFS_INCR_NODES();
- return 0;
+ if (error) {
+ FREE(dnp, M_DEVFSNODE);
+ } else {
+ *dn_pp = dnp;
+ DEVFS_INCR_NODES();
+ }
+
+ return error;
}
}
/* Can only free if there are no references; otherwise, wait for last vnode to be reclaimed */
- if (dnp->dn_refcount == 0) {
+ os_ref_count_t rc = os_ref_get_count_raw(&dnp->dn_refcount);
+ if (rc == 1) {
+ /* release final reference from dev_add_node */
+ (void) os_ref_release_locked_raw(&dnp->dn_refcount, &devfs_refgrp);
devnode_free(dnp);
} else {
dnp->dn_lflags |= DN_DELETE;
void
devfs_ref_node(devnode_t *dnp)
{
- dnp->dn_refcount++;
+ os_ref_retain_locked_raw(&dnp->dn_refcount, &devfs_refgrp);
}
/*
* Release a reference on a devnode. If the devnode is marked for
- * free and the refcount is dropped to zero, do the free.
+ * free and the refcount is dropped to one, do the free.
*/
void
devfs_rele_node(devnode_t *dnp)
{
- dnp->dn_refcount--;
- if (dnp->dn_refcount < 0) {
- panic("devfs_rele_node: devnode with a negative refcount!\n");
- } else if ((dnp->dn_refcount == 0) && (dnp->dn_lflags & DN_DELETE)) {
+ os_ref_count_t rc = os_ref_release_locked_raw(&dnp->dn_refcount, &devfs_refgrp);
+ if (rc < 1) {
+ panic("devfs_rele_node: devnode without a refcount!\n");
+ } else if ((rc == 1) && (dnp->dn_lflags & DN_DELETE)) {
+ /* release final reference from dev_add_node */
+ (void) os_ref_release_locked_raw(&dnp->dn_refcount, &devfs_refgrp);
devnode_free(dnp);
}
}
#if CONFIG_MACF
char buff[sizeof(buf)];
#endif
- int i;
+ size_t i;
uint32_t log_count;
struct devfs_event_log event_log;
struct devfs_vnode_event stackbuf[NUM_STACK_ENTRIES];
va_list ap;
char *p, buf[256]; /* XXX */
- int i;
+ size_t i;
DEVFS_LOCK();