Skip to content

Commit 264725e

Browse files
committed
mtd: Clean refcounting with MTD_PARTITIONED_MASTER
The logic is way too convoluted, let's clean the kref_get/put section to clarify what this block does when using CONFIG_MTD_PARTITIONED_MASTER: - Iterate through all the parent mtd devices - Grab a reference over them all but the master - Only grab the master whith CONFIG_MTD_PARTITIONED_MASTER Same logic must apply in the put path, otherwise it would be broken. Cc: Tomas Winkler <tomas.winkler@intel.com> Cc: Alexander Usyskin <alexander.usyskin@intel.com> Cc: Zhang Xiaoxu <zhangxiaoxu5@huawei.com> Fixes: 19bfa9e ("mtd: use refcount to prevent corruption") Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Tested-by: Alexander Usyskin <alexander.usyskin@intel.com> Link: https://lore.kernel.org/linux-mtd/20230731090903.770277-1-miquel.raynal@bootlin.com
1 parent e9714c2 commit 264725e

File tree

1 file changed

+10
-7
lines changed

1 file changed

+10
-7
lines changed

drivers/mtd/mtdcore.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,14 +1247,15 @@ int __get_mtd_device(struct mtd_info *mtd)
12471247
return -ENODEV;
12481248
}
12491249

1250-
kref_get(&mtd->refcnt);
1251-
1252-
while (mtd->parent) {
1253-
if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER) || mtd->parent != master)
1254-
kref_get(&mtd->parent->refcnt);
1250+
while (mtd) {
1251+
if (mtd != master)
1252+
kref_get(&mtd->refcnt);
12551253
mtd = mtd->parent;
12561254
}
12571255

1256+
if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
1257+
kref_get(&master->refcnt);
1258+
12581259
return 0;
12591260
}
12601261
EXPORT_SYMBOL_GPL(__get_mtd_device);
@@ -1338,10 +1339,12 @@ void __put_mtd_device(struct mtd_info *mtd)
13381339
{
13391340
struct mtd_info *master = mtd_get_master(mtd);
13401341

1341-
while (mtd != master) {
1342+
while (mtd) {
1343+
/* kref_put() can relese mtd, so keep a reference mtd->parent */
13421344
struct mtd_info *parent = mtd->parent;
13431345

1344-
kref_put(&mtd->refcnt, mtd_device_release);
1346+
if (mtd != master)
1347+
kref_put(&mtd->refcnt, mtd_device_release);
13451348
mtd = parent;
13461349
}
13471350

0 commit comments

Comments
 (0)