Changeset View
Changeset View
Standalone View
Standalone View
head/sys/fs/pseudofs/pseudofs.c
Show First 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | |||||
#if PFS_FSNAMELEN != MFSNAMELEN | #if PFS_FSNAMELEN != MFSNAMELEN | ||||
#error "PFS_FSNAMELEN is not equal to MFSNAMELEN" | #error "PFS_FSNAMELEN is not equal to MFSNAMELEN" | ||||
#endif | #endif | ||||
/* | /* | ||||
* Allocate and initialize a node | * Allocate and initialize a node | ||||
*/ | */ | ||||
static struct pfs_node * | static struct pfs_node * | ||||
pfs_alloc_node(struct pfs_info *pi, const char *name, pfs_type_t type) | pfs_alloc_node_flags(struct pfs_info *pi, const char *name, pfs_type_t type, int flags) | ||||
{ | { | ||||
struct pfs_node *pn; | struct pfs_node *pn; | ||||
int malloc_flags; | |||||
KASSERT(strlen(name) < PFS_NAMELEN, | KASSERT(strlen(name) < PFS_NAMELEN, | ||||
("%s(): node name is too long", __func__)); | ("%s(): node name is too long", __func__)); | ||||
if (flags & PFS_NOWAIT) | |||||
pn = malloc(sizeof *pn, | malloc_flags = M_NOWAIT | M_ZERO; | ||||
M_PFSNODES, M_WAITOK|M_ZERO); | else | ||||
malloc_flags = M_WAITOK | M_ZERO; | |||||
pn = malloc(sizeof *pn, M_PFSNODES, malloc_flags); | |||||
if (pn == NULL) | |||||
return (NULL); | |||||
mtx_init(&pn->pn_mutex, "pfs_node", NULL, MTX_DEF | MTX_DUPOK); | mtx_init(&pn->pn_mutex, "pfs_node", NULL, MTX_DEF | MTX_DUPOK); | ||||
strlcpy(pn->pn_name, name, sizeof pn->pn_name); | strlcpy(pn->pn_name, name, sizeof pn->pn_name); | ||||
pn->pn_type = type; | pn->pn_type = type; | ||||
pn->pn_info = pi; | pn->pn_info = pi; | ||||
return (pn); | return (pn); | ||||
} | } | ||||
static struct pfs_node * | |||||
pfs_alloc_node(struct pfs_info *pi, const char *name, pfs_type_t type) | |||||
{ | |||||
return (pfs_alloc_node_flags(pi, name, type, 0)); | |||||
} | |||||
/* | /* | ||||
* Add a node to a directory | * Add a node to a directory | ||||
*/ | */ | ||||
static void | static void | ||||
pfs_add_node(struct pfs_node *parent, struct pfs_node *pn) | pfs_add_node(struct pfs_node *parent, struct pfs_node *pn) | ||||
{ | { | ||||
#ifdef INVARIANTS | #ifdef INVARIANTS | ||||
struct pfs_node *iter; | struct pfs_node *iter; | ||||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | pfs_detach_node(struct pfs_node *pn) | ||||
} | } | ||||
pn->pn_parent = NULL; | pn->pn_parent = NULL; | ||||
pfs_unlock(parent); | pfs_unlock(parent); | ||||
} | } | ||||
/* | /* | ||||
* Add . and .. to a directory | * Add . and .. to a directory | ||||
*/ | */ | ||||
static int | |||||
pfs_fixup_dir_flags(struct pfs_node *parent, int flags) | |||||
{ | |||||
struct pfs_node *dot, *dotdot; | |||||
dot = pfs_alloc_node_flags(parent->pn_info, ".", pfstype_this, flags); | |||||
if (dot == NULL) | |||||
return (ENOMEM); | |||||
dotdot = pfs_alloc_node_flags(parent->pn_info, "..", pfstype_parent, flags); | |||||
if (dotdot == NULL) { | |||||
pfs_destroy(dot); | |||||
return (ENOMEM); | |||||
} | |||||
pfs_add_node(parent, dot); | |||||
pfs_add_node(parent, dotdot); | |||||
return (0); | |||||
} | |||||
static void | static void | ||||
pfs_fixup_dir(struct pfs_node *parent) | pfs_fixup_dir(struct pfs_node *parent) | ||||
{ | { | ||||
struct pfs_node *pn; | |||||
pn = pfs_alloc_node(parent->pn_info, ".", pfstype_this); | pfs_fixup_dir_flags(parent, 0); | ||||
pfs_add_node(parent, pn); | |||||
pn = pfs_alloc_node(parent->pn_info, "..", pfstype_parent); | |||||
pfs_add_node(parent, pn); | |||||
} | } | ||||
/* | /* | ||||
* Create a directory | * Create a directory | ||||
*/ | */ | ||||
struct pfs_node * | struct pfs_node * | ||||
pfs_create_dir(struct pfs_node *parent, const char *name, | pfs_create_dir(struct pfs_node *parent, const char *name, | ||||
pfs_attr_t attr, pfs_vis_t vis, pfs_destroy_t destroy, | pfs_attr_t attr, pfs_vis_t vis, pfs_destroy_t destroy, | ||||
int flags) | int flags) | ||||
{ | { | ||||
struct pfs_node *pn; | struct pfs_node *pn; | ||||
int rc; | |||||
pn = pfs_alloc_node(parent->pn_info, name, | pn = pfs_alloc_node_flags(parent->pn_info, name, | ||||
(flags & PFS_PROCDEP) ? pfstype_procdir : pfstype_dir); | (flags & PFS_PROCDEP) ? pfstype_procdir : pfstype_dir, flags); | ||||
if (pn == NULL) | |||||
return (NULL); | |||||
pn->pn_attr = attr; | pn->pn_attr = attr; | ||||
pn->pn_vis = vis; | pn->pn_vis = vis; | ||||
pn->pn_destroy = destroy; | pn->pn_destroy = destroy; | ||||
pn->pn_flags = flags; | pn->pn_flags = flags; | ||||
pfs_add_node(parent, pn); | pfs_add_node(parent, pn); | ||||
pfs_fixup_dir(pn); | rc = pfs_fixup_dir_flags(pn, flags); | ||||
if (rc) { | |||||
pfs_destroy(pn); | |||||
return (NULL); | |||||
} | |||||
return (pn); | return (pn); | ||||
} | } | ||||
/* | /* | ||||
* Create a file | * Create a file | ||||
*/ | */ | ||||
struct pfs_node * | struct pfs_node * | ||||
pfs_create_file(struct pfs_node *parent, const char *name, pfs_fill_t fill, | pfs_create_file(struct pfs_node *parent, const char *name, pfs_fill_t fill, | ||||
pfs_attr_t attr, pfs_vis_t vis, pfs_destroy_t destroy, | pfs_attr_t attr, pfs_vis_t vis, pfs_destroy_t destroy, | ||||
int flags) | int flags) | ||||
{ | { | ||||
struct pfs_node *pn; | struct pfs_node *pn; | ||||
pn = pfs_alloc_node(parent->pn_info, name, pfstype_file); | pn = pfs_alloc_node_flags(parent->pn_info, name, pfstype_file, flags); | ||||
if (pn == NULL) | |||||
return (NULL); | |||||
pn->pn_fill = fill; | pn->pn_fill = fill; | ||||
pn->pn_attr = attr; | pn->pn_attr = attr; | ||||
pn->pn_vis = vis; | pn->pn_vis = vis; | ||||
pn->pn_destroy = destroy; | pn->pn_destroy = destroy; | ||||
pn->pn_flags = flags; | pn->pn_flags = flags; | ||||
pfs_add_node(parent, pn); | pfs_add_node(parent, pn); | ||||
return (pn); | return (pn); | ||||
} | } | ||||
/* | /* | ||||
* Create a symlink | * Create a symlink | ||||
*/ | */ | ||||
struct pfs_node * | struct pfs_node * | ||||
pfs_create_link(struct pfs_node *parent, const char *name, pfs_fill_t fill, | pfs_create_link(struct pfs_node *parent, const char *name, pfs_fill_t fill, | ||||
pfs_attr_t attr, pfs_vis_t vis, pfs_destroy_t destroy, | pfs_attr_t attr, pfs_vis_t vis, pfs_destroy_t destroy, | ||||
int flags) | int flags) | ||||
{ | { | ||||
struct pfs_node *pn; | struct pfs_node *pn; | ||||
pn = pfs_alloc_node(parent->pn_info, name, pfstype_symlink); | pn = pfs_alloc_node_flags(parent->pn_info, name, pfstype_symlink, flags); | ||||
if (pn == NULL) | |||||
return (NULL); | |||||
pn->pn_fill = fill; | pn->pn_fill = fill; | ||||
pn->pn_attr = attr; | pn->pn_attr = attr; | ||||
pn->pn_vis = vis; | pn->pn_vis = vis; | ||||
pn->pn_destroy = destroy; | pn->pn_destroy = destroy; | ||||
pn->pn_flags = flags; | pn->pn_flags = flags; | ||||
pfs_add_node(parent, pn); | pfs_add_node(parent, pn); | ||||
return (pn); | return (pn); | ||||
▲ Show 20 Lines • Show All 221 Lines • Show Last 20 Lines |