/* Called with devfs locked */ int devfs_make_symlink(devnode_t *dir_p, char *name, int mode, char *target, devdirent_t **newent) { int error = 0; devnode_type_t typeinfo; devdirent_t * nm_p; devnode_t * dev_p; typeinfo.Slnk.name = target; typeinfo.Slnk.namelen = strlen(target); error = dev_add_entry(name, dir_p, DEV_SLNK, &typeinfo, NULL, NULL, &nm_p); if (error) { goto failure; } dev_p = nm_p->de_dnp; dev_p->dn_uid = dir_p->dn_uid; dev_p->dn_gid = dir_p->dn_gid; dev_p->dn_mode = mode; dn_copy_times(dev_p, dir_p); if (newent) { *newent = nm_p; } failure: return error; }
/* * Mknod vnode call */ static int devfs_mknod(struct vnop_mknod_args *ap) /* struct vnop_mknod_args { struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; struct vnode_attr *a_vap; vfs_context_t a_context; } */ { struct componentname * cnp = ap->a_cnp; vfs_context_t ctx = cnp->cn_context; struct proc *p = vfs_context_proc(ctx); devnode_t * dev_p; devdirent_t * devent; devnode_t * dir_p; /* devnode for parent directory */ struct vnode * dvp = ap->a_dvp; int error = 0; devnode_type_t typeinfo; struct vnode_attr * vap = ap->a_vap; struct vnode ** vpp = ap->a_vpp; *vpp = NULL; if (!(vap->va_type == VBLK) && !(vap->va_type == VCHR)) { return (EINVAL); /* only support mknod of special files */ } typeinfo.dev = vap->va_rdev; DEVFS_LOCK(); dir_p = VTODN(dvp); error = dev_add_entry(cnp->cn_nameptr, dir_p, (vap->va_type == VBLK) ? DEV_BDEV : DEV_CDEV, &typeinfo, NULL, NULL, &devent); if (error) { goto failure; } dev_p = devent->de_dnp; error = devfs_dntovn(dev_p, vpp, p); if (error) goto failure; dev_p->dn_uid = vap->va_uid; dev_p->dn_gid = vap->va_gid; dev_p->dn_mode = vap->va_mode; VATTR_SET_SUPPORTED(vap, va_uid); VATTR_SET_SUPPORTED(vap, va_gid); VATTR_SET_SUPPORTED(vap, va_mode); failure: DEVFS_UNLOCK(); return (error); }
static int devfs_symlink(struct vnop_symlink_args *ap) /*struct vnop_symlink_args { struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; struct vnode_attr *a_vap; char *a_target; vfs_context_t a_context; } */ { struct componentname * cnp = ap->a_cnp; vfs_context_t ctx = cnp->cn_context; struct proc *p = vfs_context_proc(ctx); int error = 0; devnode_t * dir_p; devnode_type_t typeinfo; devdirent_t * nm_p; devnode_t * dev_p; struct vnode_attr * vap = ap->a_vap; struct vnode * * vpp = ap->a_vpp; typeinfo.Slnk.name = ap->a_target; typeinfo.Slnk.namelen = strlen(ap->a_target); DEVFS_LOCK(); dir_p = VTODN(ap->a_dvp); error = dev_add_entry(cnp->cn_nameptr, dir_p, DEV_SLNK, &typeinfo, NULL, NULL, &nm_p); if (error) { goto failure; } dev_p = nm_p->de_dnp; dev_p->dn_uid = dir_p->dn_uid; dev_p->dn_gid = dir_p->dn_gid; dev_p->dn_mode = vap->va_mode; dn_copy_times(dev_p, dir_p); error = devfs_dntovn(dev_p, vpp, p); failure: DEVFS_UNLOCK(); return error; }
static int devfs_mkdir(struct vnop_mkdir_args *ap) /*struct vnop_mkdir_args { struct vnode *a_dvp; struct vnode **a_vpp; struct componentname *a_cnp; struct vnode_attr *a_vap; vfs_context_t a_context; } */ { struct componentname * cnp = ap->a_cnp; vfs_context_t ctx = cnp->cn_context; struct proc *p = vfs_context_proc(ctx); int error = 0; devnode_t * dir_p; devdirent_t * nm_p; devnode_t * dev_p; struct vnode_attr * vap = ap->a_vap; struct vnode * * vpp = ap->a_vpp; DEVFS_LOCK(); dir_p = VTODN(ap->a_dvp); error = dev_add_entry(cnp->cn_nameptr, dir_p, DEV_DIR, NULL, NULL, NULL, &nm_p); if (error) { goto failure; } dev_p = nm_p->de_dnp; dev_p->dn_uid = dir_p->dn_uid; dev_p->dn_gid = dir_p->dn_gid; dev_p->dn_mode = vap->va_mode; dn_copy_times(dev_p, dir_p); error = devfs_dntovn(dev_p, vpp, p); failure: DEVFS_UNLOCK(); return error; }