int procfs_register(FAR const struct procfs_entry_s *entry) { FAR struct procfs_entry_s *newtable; unsigned int newcount; size_t newsize; int ret; /* Make sure that we are properly initialized */ procfs_initialize(); /* realloc the table of procfs entries. * * REVISIT: This reallocation may free memory previously used for the * procfs entry table. If that table were actively in use, then that * could cause procfs logic to use a stale memory pointer! We avoid that * problem by requiring that the procfs file be unmounted when the new * entry is added. That requirment, however, is not enforced explicitly. * * Locking the scheduler as done below is insufficient. As would be just * marking the entries as volatile. */ newcount = g_procfs_entrycount + 1; newsize = newcount * sizeof(struct procfs_entry_s); sched_lock(); newtable = (FAR struct procfs_entry_s *)kmm_realloc(g_procfs_entries, newsize); if (newtable == NULL) { /* Reallocation failed! */ ret = -ENOMEM; } else { /* Copy the new entry at the end of the reallocated table */ memcpy(&newtable[g_procfs_entrycount], entry, sizeof(struct procfs_entry_s)); /* Instantiate the reallocated table */ g_procfs_entries = newtable; g_procfs_entrycount = newcount; ret = OK; } sched_unlock(); return ret; }
int elf_reallocbuffer(FAR struct elf_loadinfo_s *loadinfo, size_t increment) { FAR void *buffer; size_t newsize; /* Get the new size of the allocation */ newsize = loadinfo->buflen + increment; /* And perform the reallocation */ buffer = kmm_realloc((FAR void *)loadinfo->iobuffer, newsize); if (!buffer) { bdbg("Failed to reallocate the I/O buffer\n"); return -ENOMEM; } /* Save the new buffer info */ loadinfo->iobuffer = buffer; loadinfo->buflen = newsize; return OK; }
int usbmsc_bindlun(FAR void *handle, FAR const char *drvrpath, unsigned int lunno, off_t startsector, size_t nsectors, bool readonly) { FAR struct usbmsc_alloc_s *alloc = (FAR struct usbmsc_alloc_s *)handle; FAR struct usbmsc_dev_s *priv; FAR struct usbmsc_lun_s *lun; FAR struct inode *inode; struct geometry geo; int ret; #ifdef CONFIG_DEBUG if (!alloc || !drvrpath || startsector < 0) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_BINLUNINVALIDARGS1), 0); return -EINVAL; } #endif priv = &alloc->dev; #ifdef CONFIG_DEBUG if (!priv->luntab) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_INTERNALCONFUSION1), 0); return -EIO; } if (lunno > priv->nluns) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_BINDLUNINVALIDARGS2), 0); return -EINVAL; } #endif lun = &priv->luntab[lunno]; #ifdef CONFIG_DEBUG if (lun->inode != NULL) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_LUNALREADYBOUND), 0); return -EBUSY; } #endif /* Open the block driver */ ret = open_blockdriver(drvrpath, 0, &inode); if (ret < 0) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_BLKDRVEOPEN), 0); return ret; } /* Get the drive geometry */ if (!inode || !inode->u.i_bops || !inode->u.i_bops->geometry || inode->u.i_bops->geometry(inode, &geo) != OK || !geo.geo_available) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_NOGEOMETRY), 0); return -ENODEV; } /* Verify that the partition parameters are valid */ if (startsector >= geo.geo_nsectors) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_BINDLUNINVALIDARGS3), 0); return -EDOM; } else if (nsectors == 0) { nsectors = geo.geo_nsectors - startsector; } else if (startsector + nsectors >= geo.geo_nsectors) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_BINDLUNINVALIDARGS4), 0); return -EDOM; } /* Initialize the LUN structure */ memset(lun, 0, sizeof(struct usbmsc_lun_s *)); /* Allocate an I/O buffer big enough to hold one hardware sector. SCSI commands * are processed one at a time so all LUNs may share a single I/O buffer. The * I/O buffer will be allocated so that is it as large as the largest block * device sector size */ if (!priv->iobuffer) { priv->iobuffer = (FAR uint8_t *)kmm_malloc(geo.geo_sectorsize); if (!priv->iobuffer) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_ALLOCIOBUFFER), geo.geo_sectorsize); return -ENOMEM; } priv->iosize = geo.geo_sectorsize; } else if (priv->iosize < geo.geo_sectorsize) { void *tmp; tmp = (FAR uint8_t *)kmm_realloc(priv->iobuffer, geo.geo_sectorsize); if (!tmp) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_REALLOCIOBUFFER), geo.geo_sectorsize); return -ENOMEM; } priv->iobuffer = (FAR uint8_t *)tmp; priv->iosize = geo.geo_sectorsize; } lun->inode = inode; lun->startsector = startsector; lun->nsectors = nsectors; lun->sectorsize = geo.geo_sectorsize; /* If the driver does not support the write method, then this is read-only */ if (!inode->u.i_bops->write) { lun->readonly = true; } return OK; }