From 771709eb7860077f6bd23db6583a6e4bffd7f756 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Mon, 12 Mar 2007 12:16:52 +0000 Subject: [PATCH] Add a pn_destroy field to pfs_node. This field points to a destructor function which is called from pfs_destroy() before the node is reclaimed. Modify pfs_create_{dir,file,link}() to accept a pointer to a destructor function in addition to the usual attr / fill / vis pointers. This breaks both the programming and binary interfaces between pseudofs and its consumers. It is believed that there are no pseudofs consumers outside the source tree, so that the impact of this change is minimal. Submitted by: Aniruddha Bohra --- sys/compat/linprocfs/linprocfs.c | 72 ++++++++++++++++---------------- sys/compat/linsysfs/linsysfs.c | 18 ++++---- sys/fs/procfs/procfs.c | 30 ++++++------- sys/fs/pseudofs/pseudofs.c | 17 ++++++-- sys/fs/pseudofs/pseudofs.h | 19 +++++++-- 5 files changed, 89 insertions(+), 67 deletions(-) diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c index f1640deba72..318689f5765 100644 --- a/sys/compat/linprocfs/linprocfs.c +++ b/sys/compat/linprocfs/linprocfs.c @@ -1172,83 +1172,83 @@ linprocfs_init(PFS_INIT_ARGS) /* /proc/... */ pfs_create_file(root, "cmdline", &linprocfs_docmdline, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); pfs_create_file(root, "cpuinfo", &linprocfs_docpuinfo, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); pfs_create_file(root, "devices", &linprocfs_dodevices, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); pfs_create_file(root, "loadavg", &linprocfs_doloadavg, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); pfs_create_file(root, "meminfo", &linprocfs_domeminfo, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); #if 0 pfs_create_file(root, "modules", &linprocfs_domodules, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); #endif pfs_create_file(root, "mounts", &linprocfs_domtab, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); pfs_create_file(root, "mtab", &linprocfs_domtab, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); pfs_create_link(root, "self", &procfs_docurproc, - NULL, NULL, 0); + NULL, NULL, NULL, 0); pfs_create_file(root, "stat", &linprocfs_dostat, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); pfs_create_file(root, "uptime", &linprocfs_douptime, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); pfs_create_file(root, "version", &linprocfs_doversion, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); /* /proc/net/... */ - dir = pfs_create_dir(root, "net", NULL, NULL, 0); + dir = pfs_create_dir(root, "net", NULL, NULL, NULL, 0); pfs_create_file(dir, "dev", &linprocfs_donetdev, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); /* /proc//... */ - dir = pfs_create_dir(root, "pid", NULL, NULL, PFS_PROCDEP); + dir = pfs_create_dir(root, "pid", NULL, NULL, NULL, PFS_PROCDEP); pfs_create_file(dir, "cmdline", &linprocfs_doproccmdline, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); pfs_create_link(dir, "cwd", &linprocfs_doproccwd, - NULL, NULL, 0); + NULL, NULL, NULL, 0); pfs_create_file(dir, "environ", &linprocfs_doprocenviron, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); pfs_create_link(dir, "exe", &procfs_doprocfile, - NULL, &procfs_notsystem, 0); + NULL, &procfs_notsystem, NULL, 0); pfs_create_file(dir, "maps", &linprocfs_doprocmaps, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); pfs_create_file(dir, "mem", &procfs_doprocmem, - &procfs_attr, &procfs_candebug, PFS_RDWR|PFS_RAW); + &procfs_attr, &procfs_candebug, NULL, PFS_RDWR|PFS_RAW); pfs_create_link(dir, "root", &linprocfs_doprocroot, - NULL, NULL, 0); + NULL, NULL, NULL, 0); pfs_create_file(dir, "stat", &linprocfs_doprocstat, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); pfs_create_file(dir, "statm", &linprocfs_doprocstatm, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); pfs_create_file(dir, "status", &linprocfs_doprocstatus, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); /* /proc/scsi/... */ - dir = pfs_create_dir(root, "scsi", NULL, NULL, 0); + dir = pfs_create_dir(root, "scsi", NULL, NULL, NULL, 0); pfs_create_file(dir, "device_info", &linprocfs_doscsidevinfo, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); pfs_create_file(dir, "scsi", &linprocfs_doscsiscsi, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); /* /proc/sys/... */ - dir = pfs_create_dir(root, "sys", NULL, NULL, 0); + dir = pfs_create_dir(root, "sys", NULL, NULL, NULL, 0); /* /proc/sys/kernel/... */ - dir = pfs_create_dir(dir, "kernel", NULL, NULL, 0); + dir = pfs_create_dir(dir, "kernel", NULL, NULL, NULL, 0); pfs_create_file(dir, "osrelease", &linprocfs_doosrelease, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); pfs_create_file(dir, "ostype", &linprocfs_doostype, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); pfs_create_file(dir, "version", &linprocfs_doosbuild, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); pfs_create_file(dir, "msgmni", &linprocfs_domsgmni, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); pfs_create_file(dir, "pid_max", &linprocfs_dopid_max, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); pfs_create_file(dir, "sem", &linprocfs_dosem, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); return (0); } diff --git a/sys/compat/linsysfs/linsysfs.c b/sys/compat/linsysfs/linsysfs.c index cce49f79577..2247d29b73f 100644 --- a/sys/compat/linsysfs/linsysfs.c +++ b/sys/compat/linsysfs/linsysfs.c @@ -175,7 +175,7 @@ linsysfs_run_bus(device_t dev, struct pfs_node *dir, struct pfs_node *scsi, char strcat(new_path, "/"); strcat(new_path, device); dir = pfs_create_dir(dir, device, - NULL, NULL, 0); + NULL, NULL, NULL, 0); if (dinfo->cfg.baseclass == PCIC_STORAGE) { /* DJA only make this if needed */ @@ -183,7 +183,7 @@ linsysfs_run_bus(device_t dev, struct pfs_node *dir, struct pfs_node *scsi, char strcat(new_path, "/"); strcat(new_path, host); sub_dir = pfs_create_dir(dir, - host, NULL, NULL, 0); + host, NULL, NULL, NULL, 0); scsi_host = malloc(sizeof( struct scsi_host_queue), M_DEVBUF, M_NOWAIT); @@ -196,13 +196,13 @@ linsysfs_run_bus(device_t dev, struct pfs_node *dir, struct pfs_node *scsi, char scsi_host->name = "unknown"; sub_dir = pfs_create_dir(scsi, host, - NULL, NULL, 0); + NULL, NULL, NULL, 0); pfs_create_link(sub_dir, "device", &linsysfs_link_scsi_host, - NULL, NULL, 0); + NULL, NULL, NULL, 0); pfs_create_file(sub_dir, "proc_name", &linsysfs_scsiname, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); scsi_host->name = linux_driver_get_name_dev(dev); TAILQ_INSERT_TAIL(&scsi_host_q, @@ -243,14 +243,14 @@ linsysfs_init(PFS_INIT_ARGS) root = pi->pi_root; /* /sys/class/... */ - scsi = pfs_create_dir(root, "class", NULL, NULL, 0); - scsi = pfs_create_dir(scsi, "scsi_host", NULL, NULL, 0); + scsi = pfs_create_dir(root, "class", NULL, NULL, NULL, 0); + scsi = pfs_create_dir(scsi, "scsi_host", NULL, NULL, NULL, 0); /* /sys/device */ - dir = pfs_create_dir(root, "devices", NULL, NULL, 0); + dir = pfs_create_dir(root, "devices", NULL, NULL, NULL, 0); /* /sys/device/pci0000:00 */ - pci = pfs_create_dir(dir, "pci0000:00", NULL, NULL, 0); + pci = pfs_create_dir(dir, "pci0000:00", NULL, NULL, NULL, 0); devclass = devclass_find("root"); if (devclass == NULL) { diff --git a/sys/fs/procfs/procfs.c b/sys/fs/procfs/procfs.c index d311a98a527..56bc0cc0375 100644 --- a/sys/fs/procfs/procfs.c +++ b/sys/fs/procfs/procfs.c @@ -160,39 +160,39 @@ procfs_init(PFS_INIT_ARGS) root = pi->pi_root; pfs_create_link(root, "curproc", procfs_docurproc, - NULL, NULL, 0); + NULL, NULL, NULL, 0); dir = pfs_create_dir(root, "pid", - procfs_attr, NULL, PFS_PROCDEP); + procfs_attr, NULL, NULL, PFS_PROCDEP); pfs_create_file(dir, "cmdline", procfs_doproccmdline, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); pfs_create_file(dir, "ctl", procfs_doprocctl, - procfs_attr, NULL, PFS_WR); + procfs_attr, NULL, NULL, PFS_WR); pfs_create_file(dir, "dbregs", procfs_doprocdbregs, - procfs_attr, procfs_candebug, PFS_RDWR|PFS_RAW); + procfs_attr, procfs_candebug, NULL, PFS_RDWR|PFS_RAW); pfs_create_file(dir, "etype", procfs_doproctype, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); pfs_create_file(dir, "fpregs", procfs_doprocfpregs, - procfs_attr, procfs_candebug, PFS_RDWR|PFS_RAW); + procfs_attr, procfs_candebug, NULL, PFS_RDWR|PFS_RAW); pfs_create_file(dir, "map", procfs_doprocmap, - NULL, procfs_notsystem, PFS_RD); + NULL, procfs_notsystem, NULL, PFS_RD); node = pfs_create_file(dir, "mem", procfs_doprocmem, - procfs_attr, procfs_candebug, PFS_RDWR|PFS_RAW); + procfs_attr, procfs_candebug, NULL, PFS_RDWR|PFS_RAW); node->pn_ioctl = procfs_ioctl; node->pn_close = procfs_close; pfs_create_file(dir, "note", procfs_doprocnote, - procfs_attr, procfs_candebug, PFS_WR); + procfs_attr, procfs_candebug, NULL, PFS_WR); pfs_create_file(dir, "notepg", procfs_doprocnote, - procfs_attr, procfs_candebug, PFS_WR); + procfs_attr, procfs_candebug, NULL, PFS_WR); pfs_create_file(dir, "regs", procfs_doprocregs, - procfs_attr, procfs_candebug, PFS_RDWR|PFS_RAW); + procfs_attr, procfs_candebug, NULL, PFS_RDWR|PFS_RAW); pfs_create_file(dir, "rlimit", procfs_doprocrlimit, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); pfs_create_file(dir, "status", procfs_doprocstatus, - NULL, NULL, PFS_RD); + NULL, NULL, NULL, PFS_RD); pfs_create_link(dir, "file", procfs_doprocfile, - NULL, procfs_notsystem, 0); + NULL, procfs_notsystem, NULL, 0); return (0); } diff --git a/sys/fs/pseudofs/pseudofs.c b/sys/fs/pseudofs/pseudofs.c index da1758b9303..42c45bbd490 100644 --- a/sys/fs/pseudofs/pseudofs.c +++ b/sys/fs/pseudofs/pseudofs.c @@ -122,7 +122,8 @@ _pfs_fixup_dir(struct pfs_node *parent) */ struct pfs_node * pfs_create_dir(struct pfs_node *parent, const char *name, - pfs_attr_t attr, pfs_vis_t vis, int flags) + pfs_attr_t attr, pfs_vis_t vis, pfs_destroy_t destroy, + int flags) { struct pfs_node *dir; @@ -135,6 +136,7 @@ pfs_create_dir(struct pfs_node *parent, const char *name, dir->pn_type = (flags & PFS_PROCDEP) ? pfstype_procdir : pfstype_dir; dir->pn_attr = attr; dir->pn_vis = vis; + dir->pn_destroy = destroy; dir->pn_flags = flags; if (_pfs_add_node(parent, dir) != 0) { @@ -155,7 +157,8 @@ pfs_create_dir(struct pfs_node *parent, const char *name, */ struct pfs_node * pfs_create_file(struct pfs_node *parent, const char *name, pfs_fill_t fill, - pfs_attr_t attr, pfs_vis_t vis, int flags) + pfs_attr_t attr, pfs_vis_t vis, pfs_destroy_t destroy, + int flags) { struct pfs_node *node; @@ -169,6 +172,7 @@ pfs_create_file(struct pfs_node *parent, const char *name, pfs_fill_t fill, node->pn_func = fill; node->pn_attr = attr; node->pn_vis = vis; + node->pn_destroy = destroy; node->pn_flags = flags; if (_pfs_add_node(parent, node) != 0) { @@ -184,11 +188,12 @@ pfs_create_file(struct pfs_node *parent, const char *name, pfs_fill_t fill, */ struct pfs_node * pfs_create_link(struct pfs_node *parent, const char *name, pfs_fill_t fill, - pfs_attr_t attr, pfs_vis_t vis, int flags) + pfs_attr_t attr, pfs_vis_t vis, pfs_destroy_t destroy, + int flags) { struct pfs_node *node; - node = pfs_create_file(parent, name, fill, attr, vis, flags); + node = pfs_create_file(parent, name, fill, attr, vis, destroy, flags); if (node == NULL) return (NULL); node->pn_type = pfstype_symlink; @@ -249,6 +254,10 @@ pfs_destroy(struct pfs_node *node) mtx_unlock(&node->pn_info->pi_mutex); } + /* callback to free any private resources */ + if(node->pn_destroy != NULL) + (node->pn_destroy)(node); + /* revoke vnodes and release memory */ pfs_disable(node); FREE(node, M_PFSNODES); diff --git a/sys/fs/pseudofs/pseudofs.h b/sys/fs/pseudofs/pseudofs.h index b9701bc0933..58eba44b714 100644 --- a/sys/fs/pseudofs/pseudofs.h +++ b/sys/fs/pseudofs/pseudofs.h @@ -154,6 +154,15 @@ typedef int (*pfs_getextattr_t)(PFS_GETEXTATTR_ARGS); int name(PFS_CLOSE_ARGS); typedef int (*pfs_close_t)(PFS_CLOSE_ARGS); +/* + * Destroy callback + */ +#define PFS_DESTROY_ARGS \ + struct pfs_node *pn +#define PFS_DESTROY_PROTO(name) \ + int name(PFS_DESTROY_ARGS); +typedef int (*pfs_destroy_t)(PFS_DESTROY_ARGS); + /* * pfs_info: describes a pseudofs instance */ @@ -186,6 +195,7 @@ struct pfs_node { pfs_attr_t pn_attr; pfs_vis_t pn_vis; pfs_getextattr_t pn_getextattr; + pfs_destroy_t pn_destroy; void *pn_data; int pn_flags; @@ -215,13 +225,16 @@ int pfs_uninit (struct pfs_info *pi, struct vfsconf *vfc); * Directory structure construction and manipulation */ struct pfs_node *pfs_create_dir (struct pfs_node *parent, const char *name, - pfs_attr_t attr, pfs_vis_t vis, int flags); + pfs_attr_t attr, pfs_vis_t vis, + pfs_destroy_t destroy, int flags); struct pfs_node *pfs_create_file(struct pfs_node *parent, const char *name, pfs_fill_t fill, pfs_attr_t attr, - pfs_vis_t vis, int flags); + pfs_vis_t vis, pfs_destroy_t destroy, + int flags); struct pfs_node *pfs_create_link(struct pfs_node *parent, const char *name, pfs_fill_t fill, pfs_attr_t attr, - pfs_vis_t vis, int flags); + pfs_vis_t vis, pfs_destroy_t destroy, + int flags); struct pfs_node *pfs_find_node (struct pfs_node *parent, const char *name); int pfs_disable (struct pfs_node *pn); int pfs_enable (struct pfs_node *pn);