Plug a serious memory leak. The -STABLE equivalent of this patch has
been tested extensively, but -CURRENT testing has been hampered by a number of panics that also occur without the patch. Since the destabilizing changes between 4.X and 5.X are external to unionfs, I believe this patch applies equally well to both. Thanks to scrappy for assistance testing these and other changes. MFC after: 4 days
This commit is contained in:
parent
c2935410f6
commit
177935c8d6
@ -1246,12 +1246,14 @@ union_dircache(vp, td)
|
||||
int cnt;
|
||||
struct vnode *nvp;
|
||||
struct vnode **vpp;
|
||||
struct vnode **dircache;
|
||||
struct vnode **dircache, **newdircache;
|
||||
struct union_node *un;
|
||||
int error;
|
||||
|
||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
dircache = VTOUNION(vp)->un_dircache;
|
||||
un = VTOUNION(vp);
|
||||
dircache = un->un_dircache;
|
||||
newdircache = NULL;
|
||||
|
||||
nvp = NULLVP;
|
||||
|
||||
@ -1259,8 +1261,8 @@ union_dircache(vp, td)
|
||||
cnt = 0;
|
||||
union_dircache_r(vp, 0, &cnt);
|
||||
cnt++;
|
||||
dircache = malloc(cnt * sizeof(struct vnode *),
|
||||
M_TEMP, M_WAITOK);
|
||||
newdircache = dircache = malloc(cnt * sizeof(struct vnode *),
|
||||
M_TEMP, M_WAITOK);
|
||||
vpp = dircache;
|
||||
union_dircache_r(vp, &vpp, &cnt);
|
||||
*vpp = NULLVP;
|
||||
@ -1268,7 +1270,7 @@ union_dircache(vp, td)
|
||||
} else {
|
||||
vpp = dircache;
|
||||
do {
|
||||
if (*vpp++ == VTOUNION(vp)->un_uppervp)
|
||||
if (*vpp++ == un->un_uppervp)
|
||||
break;
|
||||
} while (*vpp != NULLVP);
|
||||
}
|
||||
@ -1284,11 +1286,21 @@ union_dircache(vp, td)
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
VTOUNION(vp)->un_dircache = 0;
|
||||
un = VTOUNION(nvp);
|
||||
un->un_dircache = dircache;
|
||||
un->un_dircache = NULL;
|
||||
VTOUNION(nvp)->un_dircache = dircache;
|
||||
newdircache = NULL;
|
||||
|
||||
out:
|
||||
/*
|
||||
* If we allocated a new dircache and couldn't attach
|
||||
* it to a new vp, free the resources we allocated.
|
||||
*/
|
||||
if (newdircache) {
|
||||
for (vpp = newdircache; *vpp != NULLVP; vpp++)
|
||||
vrele(*vpp);
|
||||
free(newdircache, M_TEMP);
|
||||
}
|
||||
|
||||
VOP_UNLOCK(vp, 0, td);
|
||||
return (nvp);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user