Commit 76d7adc
committed
Fix memory leak in glfs_h_create_from_handle
If the allocation of the glfs_object failed, the reference to
the newly found or linked inode was leaked. We introduce a call to
inode_unref(newinode) guarded by a check, so that the newinode does not
leak in such case. One of the paths also required a solution for the
inode_lookup case, which we also introduce.
The leak happened in two cases:
1. The inode_new Path (New Inode)
loc.inode = inode_new(): new inode, first reference (refcount = 1) owned by loc.inode.
newinode = inode_link(loc.inode, ...):
inode_link calls __inode_link -> hashes loc.inode and returns it.
inode_link then calls __inode_ref() -> inode has refcount = 2.
loc.inode <- first reference, and newinode <- second (new) reference.
2. The lookup_needed Path (Existing Inode)
newinode = inode_find(...): This finds the inode, takes reference (refcount = 1).
loc.inode = newinode: No new reference; both share the single reference.
newinode = inode_link(loc.inode, ...):
* Since the inode is already hashed, inode_link finds it and returns it.
* It then calls __inode_ref(), taking a second reference (refcount = 2).
* newinode is updated to hold this second reference, while
loc.inode effectively "keeps" the original reference from
inode_find.
In both scenarios, after inode_link you have two references to the inode.
And then we lookup the inode, increasing it's nlookup reference count:
inode_lookup(new_inode) <- nlookup++
Forward in the successful path, object->inode = newinode takes
ownership of one reference, and loc_wipe(&loc) correctly drops the temporary
reference held by loc.inode, leaving exactly one reference owned by the
glfs_object.
BUT if GF_CALLOC fails, you must call inode_unref(newinode) to drop one
reference, and then loc_wipe(&loc) handles the other. In this case, inode_unref
decrements ref, and when it hits zero, the fate of the inode depends on nlookup.
Since we inode_lookup'd, inode->nlookup > 0 and we go __inode_passivate() when
we expected __inode_retire() (inode.c:521-528).
That's why we introduce the variable, the check and the call to
decrement the nlookup reference count in the GF_CALLOC fail path before
calling inode_unref.
This closes the TODO in label 'out:' of glfs_h_create_from_handle
Signed-off-by: Thales Antunes de Oliveira Barretto <thales.barretto.git@gmail.com>1 parent ae1d696 commit 76d7adc
1 file changed
Lines changed: 6 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1415 | 1415 | | |
1416 | 1416 | | |
1417 | 1417 | | |
| 1418 | + | |
1418 | 1419 | | |
1419 | 1420 | | |
1420 | 1421 | | |
| |||
1487 | 1488 | | |
1488 | 1489 | | |
1489 | 1490 | | |
| 1491 | + | |
1490 | 1492 | | |
1491 | 1493 | | |
1492 | 1494 | | |
| |||
1502 | 1504 | | |
1503 | 1505 | | |
1504 | 1506 | | |
| 1507 | + | |
| 1508 | + | |
| 1509 | + | |
| 1510 | + | |
1505 | 1511 | | |
1506 | 1512 | | |
1507 | 1513 | | |
| |||
1510 | 1516 | | |
1511 | 1517 | | |
1512 | 1518 | | |
1513 | | - | |
1514 | 1519 | | |
1515 | 1520 | | |
1516 | 1521 | | |
| |||
0 commit comments