diff options
author | Wang Shilong <wangsl-fnst@cn.fujitsu.com> | 2013-04-17 10:00:36 -0400 |
---|---|---|
committer | Josef Bacik <jbacik@fusionio.com> | 2013-05-06 15:54:58 -0400 |
commit | 3c97185c65858d23bc02492fbd27733f1f11ea83 (patch) | |
tree | a421b1612172efe99d1471342a5535cb0494f6aa /fs/btrfs/qgroup.c | |
parent | 70023da276ed7a46201e7b0d3168b005ad82fecb (diff) |
Btrfs: fix missing check about ulist_add() in qgroup.c
ulist_add() may return -ENOMEM, fix missing check about
return value.
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Diffstat (limited to 'fs/btrfs/qgroup.c')
-rw-r--r-- | fs/btrfs/qgroup.c | 62 |
1 files changed, 44 insertions, 18 deletions
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index 4beea047f4ed..f9fb52e52bb6 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c | |||
@@ -1261,7 +1261,10 @@ int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans, | |||
1261 | 1261 | ||
1262 | ulist_reinit(tmp); | 1262 | ulist_reinit(tmp); |
1263 | /* XXX id not needed */ | 1263 | /* XXX id not needed */ |
1264 | ulist_add(tmp, qg->qgroupid, (u64)(uintptr_t)qg, GFP_ATOMIC); | 1264 | ret = ulist_add(tmp, qg->qgroupid, |
1265 | (u64)(uintptr_t)qg, GFP_ATOMIC); | ||
1266 | if (ret < 0) | ||
1267 | goto unlock; | ||
1265 | ULIST_ITER_INIT(&tmp_uiter); | 1268 | ULIST_ITER_INIT(&tmp_uiter); |
1266 | while ((tmp_unode = ulist_next(tmp, &tmp_uiter))) { | 1269 | while ((tmp_unode = ulist_next(tmp, &tmp_uiter))) { |
1267 | struct btrfs_qgroup_list *glist; | 1270 | struct btrfs_qgroup_list *glist; |
@@ -1273,9 +1276,11 @@ int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans, | |||
1273 | ++qg->refcnt; | 1276 | ++qg->refcnt; |
1274 | 1277 | ||
1275 | list_for_each_entry(glist, &qg->groups, next_group) { | 1278 | list_for_each_entry(glist, &qg->groups, next_group) { |
1276 | ulist_add(tmp, glist->group->qgroupid, | 1279 | ret = ulist_add(tmp, glist->group->qgroupid, |
1277 | (u64)(uintptr_t)glist->group, | 1280 | (u64)(uintptr_t)glist->group, |
1278 | GFP_ATOMIC); | 1281 | GFP_ATOMIC); |
1282 | if (ret < 0) | ||
1283 | goto unlock; | ||
1279 | } | 1284 | } |
1280 | } | 1285 | } |
1281 | } | 1286 | } |
@@ -1284,7 +1289,10 @@ int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans, | |||
1284 | * step 2: walk from the new root | 1289 | * step 2: walk from the new root |
1285 | */ | 1290 | */ |
1286 | ulist_reinit(tmp); | 1291 | ulist_reinit(tmp); |
1287 | ulist_add(tmp, qgroup->qgroupid, (uintptr_t)qgroup, GFP_ATOMIC); | 1292 | ret = ulist_add(tmp, qgroup->qgroupid, |
1293 | (uintptr_t)qgroup, GFP_ATOMIC); | ||
1294 | if (ret < 0) | ||
1295 | goto unlock; | ||
1288 | ULIST_ITER_INIT(&uiter); | 1296 | ULIST_ITER_INIT(&uiter); |
1289 | while ((unode = ulist_next(tmp, &uiter))) { | 1297 | while ((unode = ulist_next(tmp, &uiter))) { |
1290 | struct btrfs_qgroup *qg; | 1298 | struct btrfs_qgroup *qg; |
@@ -1305,8 +1313,10 @@ int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans, | |||
1305 | qg->tag = seq; | 1313 | qg->tag = seq; |
1306 | 1314 | ||
1307 | list_for_each_entry(glist, &qg->groups, next_group) { | 1315 | list_for_each_entry(glist, &qg->groups, next_group) { |
1308 | ulist_add(tmp, glist->group->qgroupid, | 1316 | ret = ulist_add(tmp, glist->group->qgroupid, |
1309 | (uintptr_t)glist->group, GFP_ATOMIC); | 1317 | (uintptr_t)glist->group, GFP_ATOMIC); |
1318 | if (ret < 0) | ||
1319 | goto unlock; | ||
1310 | } | 1320 | } |
1311 | } | 1321 | } |
1312 | 1322 | ||
@@ -1324,7 +1334,10 @@ int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans, | |||
1324 | continue; | 1334 | continue; |
1325 | 1335 | ||
1326 | ulist_reinit(tmp); | 1336 | ulist_reinit(tmp); |
1327 | ulist_add(tmp, qg->qgroupid, (uintptr_t)qg, GFP_ATOMIC); | 1337 | ret = ulist_add(tmp, qg->qgroupid, |
1338 | (uintptr_t)qg, GFP_ATOMIC); | ||
1339 | if (ret < 0) | ||
1340 | goto unlock; | ||
1328 | ULIST_ITER_INIT(&tmp_uiter); | 1341 | ULIST_ITER_INIT(&tmp_uiter); |
1329 | while ((tmp_unode = ulist_next(tmp, &tmp_uiter))) { | 1342 | while ((tmp_unode = ulist_next(tmp, &tmp_uiter))) { |
1330 | struct btrfs_qgroup_list *glist; | 1343 | struct btrfs_qgroup_list *glist; |
@@ -1340,9 +1353,11 @@ int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans, | |||
1340 | } | 1353 | } |
1341 | 1354 | ||
1342 | list_for_each_entry(glist, &qg->groups, next_group) { | 1355 | list_for_each_entry(glist, &qg->groups, next_group) { |
1343 | ulist_add(tmp, glist->group->qgroupid, | 1356 | ret = ulist_add(tmp, glist->group->qgroupid, |
1344 | (uintptr_t)glist->group, | 1357 | (uintptr_t)glist->group, |
1345 | GFP_ATOMIC); | 1358 | GFP_ATOMIC); |
1359 | if (ret < 0) | ||
1360 | goto unlock; | ||
1346 | } | 1361 | } |
1347 | } | 1362 | } |
1348 | } | 1363 | } |
@@ -1607,7 +1622,10 @@ int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes) | |||
1607 | ret = -ENOMEM; | 1622 | ret = -ENOMEM; |
1608 | goto out; | 1623 | goto out; |
1609 | } | 1624 | } |
1610 | ulist_add(ulist, qgroup->qgroupid, (uintptr_t)qgroup, GFP_ATOMIC); | 1625 | ret = ulist_add(ulist, qgroup->qgroupid, |
1626 | (uintptr_t)qgroup, GFP_ATOMIC); | ||
1627 | if (ret < 0) | ||
1628 | goto out; | ||
1611 | ULIST_ITER_INIT(&uiter); | 1629 | ULIST_ITER_INIT(&uiter); |
1612 | while ((unode = ulist_next(ulist, &uiter))) { | 1630 | while ((unode = ulist_next(ulist, &uiter))) { |
1613 | struct btrfs_qgroup *qg; | 1631 | struct btrfs_qgroup *qg; |
@@ -1630,11 +1648,13 @@ int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes) | |||
1630 | } | 1648 | } |
1631 | 1649 | ||
1632 | list_for_each_entry(glist, &qg->groups, next_group) { | 1650 | list_for_each_entry(glist, &qg->groups, next_group) { |
1633 | ulist_add(ulist, glist->group->qgroupid, | 1651 | ret = ulist_add(ulist, glist->group->qgroupid, |
1634 | (uintptr_t)glist->group, GFP_ATOMIC); | 1652 | (uintptr_t)glist->group, GFP_ATOMIC); |
1653 | if (ret < 0) | ||
1654 | goto out; | ||
1635 | } | 1655 | } |
1636 | } | 1656 | } |
1637 | 1657 | ret = 0; | |
1638 | /* | 1658 | /* |
1639 | * no limits exceeded, now record the reservation into all qgroups | 1659 | * no limits exceeded, now record the reservation into all qgroups |
1640 | */ | 1660 | */ |
@@ -1663,6 +1683,7 @@ void btrfs_qgroup_free(struct btrfs_root *root, u64 num_bytes) | |||
1663 | struct ulist_node *unode; | 1683 | struct ulist_node *unode; |
1664 | struct ulist_iterator uiter; | 1684 | struct ulist_iterator uiter; |
1665 | u64 ref_root = root->root_key.objectid; | 1685 | u64 ref_root = root->root_key.objectid; |
1686 | int ret = 0; | ||
1666 | 1687 | ||
1667 | if (!is_fstree(ref_root)) | 1688 | if (!is_fstree(ref_root)) |
1668 | return; | 1689 | return; |
@@ -1685,7 +1706,10 @@ void btrfs_qgroup_free(struct btrfs_root *root, u64 num_bytes) | |||
1685 | btrfs_std_error(fs_info, -ENOMEM); | 1706 | btrfs_std_error(fs_info, -ENOMEM); |
1686 | goto out; | 1707 | goto out; |
1687 | } | 1708 | } |
1688 | ulist_add(ulist, qgroup->qgroupid, (uintptr_t)qgroup, GFP_ATOMIC); | 1709 | ret = ulist_add(ulist, qgroup->qgroupid, |
1710 | (uintptr_t)qgroup, GFP_ATOMIC); | ||
1711 | if (ret < 0) | ||
1712 | goto out; | ||
1689 | ULIST_ITER_INIT(&uiter); | 1713 | ULIST_ITER_INIT(&uiter); |
1690 | while ((unode = ulist_next(ulist, &uiter))) { | 1714 | while ((unode = ulist_next(ulist, &uiter))) { |
1691 | struct btrfs_qgroup *qg; | 1715 | struct btrfs_qgroup *qg; |
@@ -1696,8 +1720,10 @@ void btrfs_qgroup_free(struct btrfs_root *root, u64 num_bytes) | |||
1696 | qg->reserved -= num_bytes; | 1720 | qg->reserved -= num_bytes; |
1697 | 1721 | ||
1698 | list_for_each_entry(glist, &qg->groups, next_group) { | 1722 | list_for_each_entry(glist, &qg->groups, next_group) { |
1699 | ulist_add(ulist, glist->group->qgroupid, | 1723 | ret = ulist_add(ulist, glist->group->qgroupid, |
1700 | (uintptr_t)glist->group, GFP_ATOMIC); | 1724 | (uintptr_t)glist->group, GFP_ATOMIC); |
1725 | if (ret < 0) | ||
1726 | goto out; | ||
1701 | } | 1727 | } |
1702 | } | 1728 | } |
1703 | 1729 | ||