ref: 9e8a7578f063f4caa5ceae9b997ff72a88dbaa58
parent: 0afd20e4c409ea8b05916654783150c87dfa0c33
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Jun 3 12:58:13 EDT 2023
devsd: Fix memory leaks, wstst check, cleanup Free all the name and user strings of the partitions and files of a unit when removing a device. Reorder wstat check, so we only modify the state once all checks are done (committed). Cleanup the code, use explicit comparsions with nil for pointers. Use (*) for indirect function calls...
--- a/sys/src/9/port/devsd.c
+++ b/sys/src/9/port/devsd.c
@@ -78,8 +78,38 @@
#define QID(d,u, p, t) (((d)<<DevSHIFT)|((u)<<UnitSHIFT)|\
((p)<<PartSHIFT)|((t)<<TypeSHIFT))
+static void
+freeperm(SDperm *perm)
+{
+ free(perm->name);
+ perm->name = nil;
+ free(perm->user);
+ perm->user = nil;
+}
static void
+freeunit(SDunit *unit)
+{
+ int i;
+
+ if(unit == nil)
+ return;
+
+ for(i = 0; i < unit->nefile; i++)
+ freeperm(&unit->efile[i]);
+
+ for(i = 0; i < unit->npart; i++)
+ freeperm(&unit->part[i]);
+ free(unit->part);
+
+ freeperm(&unit->ctlperm);
+ freeperm(&unit->rawperm);
+ freeperm(unit);
+
+ free(unit);
+}
+
+static void
sdaddpart(SDunit* unit, char* name, uvlong start, uvlong end)
{
SDpart *pp;
@@ -204,8 +234,9 @@
return 0;
}
- if(unit->dev->ifc->online)
- unit->dev->ifc->online(unit);
+ if(unit->dev->ifc->online != nil)
+ (*unit->dev->ifc->online)(unit);
+
if(unit->sectors){
sdincvers(unit);
sdaddpart(unit, "data", 0, unit->sectors);
@@ -220,7 +251,7 @@
*/
snprint(buf, sizeof buf, "%spart", unit->name);
for(p = getconf(buf); p != nil; p = q){
- if(q = strchr(p, '/'))
+ if((q = strchr(p, '/')) != nil)
*q++ = '\0';
nf = tokenize(p, f, nelem(f));
if(nf < 3)
@@ -259,7 +290,7 @@
return nil;
qlock(&devslock);
- if(sdev = devs[i])
+ if((sdev = devs[i]) != nil)
incref(&sdev->r);
qunlock(&devslock);
return sdev;
@@ -303,8 +334,8 @@
if(waserror())
goto Error;
- if(sdev->enabled == 0)
- sdev->enabled = sdev->ifc->enable == nil || sdev->ifc->enable(sdev);
+ if(!sdev->enabled)
+ sdev->enabled = sdev->ifc->enable == nil || (*sdev->ifc->enable)(sdev);
/*
* No need to lock anything here as this is only
@@ -311,13 +342,11 @@
* called before the unit is made available in the
* sdunit[] array.
*/
- if(sdev->enabled == 0 || sdev->ifc->verify(unit) == 0){
+ if(!sdev->enabled || (*sdev->ifc->verify)(unit) == 0){
poperror();
Error:
qunlock(&sdev->unitlock);
- free(unit->name);
- free(unit->user);
- free(unit);
+ freeunit(unit);
return nil;
}
poperror();
@@ -351,15 +380,15 @@
for(; sdev; sdev=next){
next = sdev->next;
- sdev->unit = malloc(sdev->nunit * sizeof(SDunit*));
- sdev->unitflg = malloc(sdev->nunit * sizeof(int));
+ sdev->unit = malloc(sdev->nunit * sizeof(sdev->unit[0]));
+ sdev->unitflg = malloc(sdev->nunit * sizeof(sdev->unitflg[0]));
if(sdev->unit == nil || sdev->unitflg == nil){
print("sdadddevs: out of memory\n");
giveup:
- if(sdev->ifc->clear)
- sdev->ifc->clear(sdev);
- free(sdev->unit);
+ if(sdev->ifc->clear != nil)
+ (*sdev->ifc->clear)(sdev);
free(sdev->unitflg);
+ free(sdev->unit);
free(sdev);
continue;
}
@@ -385,15 +414,6 @@
}
}
-// void
-// sdrmdevs(SDev *sdev)
-// {
-// char buf[2];
-//
-// snprint(buf, sizeof buf, "%c", sdev->idno);
-// unconfigure(buf);
-// }
-
static int
sd2gen(Chan* c, SDunit *unit, int i, Dir* dp)
{
@@ -464,7 +484,7 @@
mkqid(&q, QID(0, 0, 0, Qtopctl), 0, QTFILE);
qlock(&topctlunit.ctl);
p = &topctlunit.ctlperm;
- if(p->user == nil || p->user[0] == 0){
+ if(emptystr(p->user)){
kstrdup(&p->name, "sdctl");
kstrdup(&p->user, eve);
p->perm = 0640;
@@ -579,7 +599,7 @@
* Online is a bit of a large hammer but does the job.
*/
if(unit->sectors == 0
- || (unit->dev->ifc->online && unit->dev->ifc->online(unit) > 1))
+ || (unit->dev->ifc->online != nil && (*unit->dev->ifc->online)(unit) > 1))
sdinitpart(unit);
i = s+Qunitbase;
@@ -657,7 +677,7 @@
if(subno < 0 || p == &spec[3])
error(Ebadspec);
- if((sdev=sdgetdev(idno)) == nil)
+ if((sdev = sdgetdev(idno)) == nil)
error(Enonexist);
if(waserror()){
decref(&sdev->r);
@@ -838,7 +858,7 @@
if(write){
if(hard){
- l = unit->dev->ifc->bio(unit, 0, 0, b, nb, bno);
+ l = (*unit->dev->ifc->bio)(unit, 0, 0, b, nb, bno);
if(l < 0)
error(Eio);
if(l < (nb*unit->secsize)){
@@ -850,7 +870,7 @@
}
if(allocd)
memmove(b+offset, a, len);
- l = unit->dev->ifc->bio(unit, 0, 1, b, nb, bno);
+ l = (*unit->dev->ifc->bio)(unit, 0, 1, b, nb, bno);
if(l < 0)
error(Eio);
if(l < offset)
@@ -859,7 +879,7 @@
len = l - offset;
}
else{
- l = unit->dev->ifc->bio(unit, 0, 0, b, nb, bno);
+ l = (*unit->dev->ifc->bio)(unit, 0, 0, b, nb, bno);
if(l < 0)
error(Eio);
if(l < offset)
@@ -928,7 +948,7 @@
}
if(f == nil)
error(errstr);
- rv = f(r);
+ rv = (*f)(r);
if(r->flags & SDvalidsense){
memmove(u->rsense, r->sense, sizeof u->rsense);
u->haversense = 1;
@@ -1215,8 +1235,8 @@
sdev = devs[i];
if(sdev == nil)
continue;
- if(sdev->ifc->rtopctl)
- p = sdev->ifc->rtopctl(sdev, p, e);
+ if(sdev->ifc->rtopctl != nil)
+ p = (*sdev->ifc->rtopctl)(sdev, p, e);
else
p = deftopctl(sdev, p, e);
}
@@ -1251,8 +1271,8 @@
* provide all information pertaining to night geometry
* and the garscadden trains.
*/
- if(unit->dev->ifc->rctl)
- p += unit->dev->ifc->rctl(unit, p, e - p);
+ if(unit->dev->ifc->rctl != nil)
+ p += (*unit->dev->ifc->rctl)(unit, p, e - p);
if(unit->sectors == 0)
sdinitpart(unit);
if(unit->sectors){
@@ -1259,12 +1279,11 @@
if(unit->dev->ifc->rctl == nil)
p = seprint(p, e, "geometry %llud %lud\n",
unit->sectors, unit->secsize);
- pp = unit->part;
for(i = 0; i < unit->npart; i++){
+ pp = &unit->part[i];
if(pp->valid)
p = seprint(p, e, "part %s %llud %llud\n",
pp->name, pp->start, pp->end);
- pp++;
}
}
qunlock(&unit->ctl);
@@ -1358,7 +1377,7 @@
*/
ifc = nil;
sdev = nil;
- for(i=0; sdifc[i]; i++){
+ for(i=0; sdifc[i] != nil; i++){
if(strcmp(sdifc[i]->name, f0) == 0){
ifc = sdifc[i];
sdev = nil;
@@ -1384,8 +1403,8 @@
decref(&sdev->r);
nexterror();
}
- if(ifc->wtopctl)
- ifc->wtopctl(sdev, cb);
+ if(ifc->wtopctl != nil)
+ (*ifc->wtopctl)(sdev, cb);
else
error(Ebadctl);
if(sdev != nil)
@@ -1423,8 +1442,8 @@
error(Ebadctl);
sddelpart(unit, cb->f[1]);
}
- else if(unit->dev->ifc->wctl)
- unit->dev->ifc->wctl(unit, cb);
+ else if(unit->dev->ifc->wctl != nil)
+ (*unit->dev->ifc->wctl)(unit, cb);
else
error(Ebadctl);
qunlock(&unit->ctl);
@@ -1558,10 +1577,11 @@
error(Eperm);
if(!emptystr(d[0].muid) || !emptystr(d[0].name))
error(Eperm);
- if(!emptystr(d[0].uid))
- kstrdup(&perm->user, d[0].uid);
if(!emptystr(d[0].gid) && strcmp(d[0].gid, eve) != 0)
error(Eperm);
+ /* committed */
+ if(!emptystr(d[0].uid))
+ kstrdup(&perm->user, d[0].uid);
if(d[0].mode != ~0UL)
perm->perm = (perm->perm & ~0777) | (d[0].mode & 0777);
qunlock(&unit->ctl);
@@ -1591,7 +1611,7 @@
break;
if(sdifc[i] == nil)
error("sd type not found");
- if(p)
+ if(p != nil)
*(p-1) = '/';
if(sdifc[i]->probe == nil)
@@ -1598,7 +1618,7 @@
error("sd type cannot probe");
sdev = sdifc[i]->probe(cf);
- for(s=sdev; s; s=s->next)
+ for(s = sdev; s != nil; s = s->next)
s->idno = *spec;
sdadddevs(sdev);
return 0;
@@ -1609,7 +1629,6 @@
{
int i;
SDev *sdev;
- SDunit *unit;
if((i = sdindex(*spec)) < 0)
error(Enonexist);
@@ -1627,23 +1646,21 @@
qunlock(&devslock);
/* make sure no interrupts arrive anymore before removing resources */
- if(sdev->enabled && sdev->ifc->disable)
- sdev->ifc->disable(sdev);
+ if(sdev->enabled && sdev->ifc->disable != nil)
+ (*sdev->ifc->disable)(sdev);
/* free controller specific info */
- if(sdev->ifc->clear)
- sdev->ifc->clear(sdev);
+ if(sdev->ifc->clear != nil)
+ (*sdev->ifc->clear)(sdev);
- for(i = 0; i < sdev->nunit; i++){
- if((unit = sdev->unit[i]) != nil){
- free(unit->name);
- free(unit->user);
- free(unit);
- }
- }
- free(sdev->unit);
+ /* free units and their files */
+ for(i = 0; i < sdev->nunit; i++)
+ freeunit(sdev->unit[i]);
+
free(sdev->unitflg);
+ free(sdev->unit);
free(sdev);
+
return 0;
}
@@ -1675,10 +1692,8 @@
if(i >= unit->nefile)
unit->nefile = i + 1;
e = unit->efile + i;
- if(e->name == nil)
- kstrdup(&e->name, s);
- if(e->user == nil)
- kstrdup(&e->user, u);
+ kstrdup(&e->name, s);
+ kstrdup(&e->user, u);
e->perm = perm;
e->r = r;
e->w = w;
@@ -1690,17 +1705,17 @@
sdshutdown(void)
{
int i;
- SDev *sd;
+ SDev *sdev;
for(i = 0; i < nelem(devs); i++){
- sd = devs[i];
- if(sd == nil)
+ sdev = devs[i];
+ if(sdev == nil)
continue;
- if(sd->ifc->disable == nil){
+ if(sdev->ifc->disable == nil){
print("#S/sd%c: no disable function\n", devletters[i]);
continue;
}
- sd->ifc->disable(sd);
+ (*sdev->ifc->disable)(sdev);
}
}
--- a/sys/src/9/port/sd.h
+++ b/sys/src/9/port/sd.h
@@ -73,7 +73,7 @@
int enabled;
int nunit; /* Number of units */
QLock unitlock; /* `Loading' of units */
- int* unitflg; /* Unit flags */
+ char* unitflg; /* Unit flags */
SDunit**unit;
};