Commit 715b56fe2b47e073e6f2425e0cedba0e92a4014d

Authored by Tom Rini
1 parent a7e8c15f71

Revert "ext4fs: Add ext4 extent cache for read operations"

This reverts commit fc0fc50f38a4d7d0554558076a79dfe8b0d78cd5.

The author has asked on the mailing list that we revert this for now as
it breaks write support.

Reported-by: Łukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Tom Rini <trini@ti.com>

Showing 3 changed files with 73 additions and 130 deletions Side-by-side Diff

fs/ext4/ext4_common.c
... ... @@ -26,7 +26,6 @@
26 26 #include <stddef.h>
27 27 #include <linux/stat.h>
28 28 #include <linux/time.h>
29   -#include <linux/list.h>
30 29 #include <asm/byteorder.h>
31 30 #include "ext4_common.h"
32 31  
... ... @@ -45,14 +44,6 @@
45 44 struct ext2_inode *g_parent_inode;
46 45 static int symlinknest;
47 46  
48   -struct ext4_extent_node {
49   - uint32_t block;
50   - uint16_t len;
51   - uint64_t start;
52   - struct list_head lh;
53   -};
54   -static LIST_HEAD(ext4_extent_lh);
55   -
56 47 #if defined(CONFIG_EXT4_WRITE)
57 48 uint32_t ext4fs_div_roundup(uint32_t size, uint32_t n)
58 49 {
59 50  
60 51  
61 52  
62 53  
63 54  
64 55  
65 56  
66 57  
67 58  
68 59  
... ... @@ -1416,102 +1407,45 @@
1416 1407  
1417 1408 #endif
1418 1409  
1419   -static void ext4fs_extent_cache_insert(struct ext4_extent_node *new)
  1410 +static struct ext4_extent_header *ext4fs_get_extent_block
  1411 + (struct ext2_data *data, char *buf,
  1412 + struct ext4_extent_header *ext_block,
  1413 + uint32_t fileblock, int log2_blksz)
1420 1414 {
1421   - struct ext4_extent_node *node;
1422   -
1423   - list_for_each_entry(node, &ext4_extent_lh, lh)
1424   - if (node->block > new->block) {
1425   - list_add_tail(&new->lh, &node->lh);
1426   - return;
1427   - }
1428   - list_add_tail(&new->lh, &ext4_extent_lh);
1429   -}
1430   -
1431   -static int __ext4fs_build_extent_cache(struct ext2_data *data,
1432   - struct ext4_extent_header *ext_block)
1433   -{
1434   - int blksz = EXT2_BLOCK_SIZE(data);
1435   - int log2_blksz = LOG2_BLOCK_SIZE(data)
1436   - - get_fs()->dev_desc->log2blksz;
1437   - struct ext4_extent_node *node;
1438 1415 struct ext4_extent_idx *index;
1439   - struct ext4_extent *extent;
1440 1416 unsigned long long block;
1441   - char *buf;
1442   - int i, err;
  1417 + int blksz = EXT2_BLOCK_SIZE(data);
  1418 + int i;
1443 1419  
1444   - if (le16_to_cpu(ext_block->eh_magic) != EXT4_EXT_MAGIC)
1445   - return -EINVAL;
  1420 + while (1) {
  1421 + index = (struct ext4_extent_idx *)(ext_block + 1);
1446 1422  
1447   - if (ext_block->eh_depth == 0) {
1448   - extent = (struct ext4_extent *)(ext_block + 1);
1449   - for (i = 0; i < le16_to_cpu(ext_block->eh_entries); i++) {
1450   - node = malloc(sizeof(*node));
1451   - if (!node)
1452   - return -ENOMEM;
1453   - node->block = le32_to_cpu(extent[i].ee_block);
1454   - node->len = le16_to_cpu(extent[i].ee_len);
1455   - node->start = le16_to_cpu(extent[i].ee_start_hi);
1456   - node->start = (node->start << 32) +
1457   - le32_to_cpu(extent[i].ee_start_lo);
1458   - ext4fs_extent_cache_insert(node);
1459   - }
1460   - return 0;
1461   - }
  1423 + if (le16_to_cpu(ext_block->eh_magic) != EXT4_EXT_MAGIC)
  1424 + return 0;
1462 1425  
1463   - index = (struct ext4_extent_idx *)(ext_block + 1);
1464   - for (i = 0; i < le16_to_cpu(ext_block->eh_entries); i++) {
1465   - buf = malloc(blksz);
1466   - if (!buf)
1467   - return -ENOMEM;
  1426 + if (ext_block->eh_depth == 0)
  1427 + return ext_block;
  1428 + i = -1;
  1429 + do {
  1430 + i++;
  1431 + if (i >= le16_to_cpu(ext_block->eh_entries))
  1432 + break;
  1433 + } while (fileblock >= le32_to_cpu(index[i].ei_block));
1468 1434  
  1435 + if (--i < 0)
  1436 + return 0;
  1437 +
1469 1438 block = le16_to_cpu(index[i].ei_leaf_hi);
1470 1439 block = (block << 32) + le32_to_cpu(index[i].ei_leaf_lo);
1471 1440  
1472   - if (!ext4fs_devread(block << log2_blksz, 0, blksz, buf)) {
1473   - free(buf);
1474   - return -EIO;
1475   - }
1476   -
1477   - err = __ext4fs_build_extent_cache(data,
1478   - (struct ext4_extent_header *) buf);
1479   - free(buf);
1480   - if (err < 0)
1481   - return err;
  1441 + if (ext4fs_devread((lbaint_t)block << log2_blksz, 0, blksz,
  1442 + buf))
  1443 + ext_block = (struct ext4_extent_header *)buf;
  1444 + else
  1445 + return 0;
1482 1446 }
1483   -
1484   - return 0;
1485 1447 }
1486 1448  
1487   -int ext4fs_build_extent_cache(struct ext2_inode *inode)
1488   -{
1489   - return __ext4fs_build_extent_cache(ext4fs_root,
1490   - (struct ext4_extent_header *)
1491   - inode->b.blocks.dir_blocks);
1492   -}
1493   -
1494   -void ext4fs_free_extent_cache(void)
1495   -{
1496   - struct ext4_extent_node *node, *tmp;
1497   -
1498   - list_for_each_entry_safe(node, tmp, &ext4_extent_lh, lh) {
1499   - list_del(&node->lh);
1500   - free(node);
1501   - }
1502   -}
1503   -
1504   -static struct ext4_extent_node *ext4fs_extent_cache_get(uint32_t block)
1505   -{
1506   - struct ext4_extent_node *node;
1507   -
1508   - list_for_each_entry(node, &ext4_extent_lh, lh)
1509   - if (block >= node->block && block < node->block + node->len)
1510   - return node;
1511   -
1512   - return NULL;
1513   -}
1514   -
1515 1449 static int ext4fs_blockgroup
1516 1450 (struct ext2_data *data, int group, struct ext2_block_group *blkgrp)
1517 1451 {
1518 1452  
1519 1453  
1520 1454  
... ... @@ -1574,22 +1508,54 @@
1574 1508 long int rblock;
1575 1509 long int perblock_parent;
1576 1510 long int perblock_child;
1577   -
  1511 + unsigned long long start;
1578 1512 /* get the blocksize of the filesystem */
1579 1513 blksz = EXT2_BLOCK_SIZE(ext4fs_root);
1580 1514 log2_blksz = LOG2_BLOCK_SIZE(ext4fs_root)
1581 1515 - get_fs()->dev_desc->log2blksz;
1582 1516  
1583 1517 if (le32_to_cpu(inode->flags) & EXT4_EXTENTS_FL) {
1584   - struct ext4_extent_node *node;
  1518 + char *buf = zalloc(blksz);
  1519 + if (!buf)
  1520 + return -ENOMEM;
  1521 + struct ext4_extent_header *ext_block;
  1522 + struct ext4_extent *extent;
  1523 + int i = -1;
  1524 + ext_block =
  1525 + ext4fs_get_extent_block(ext4fs_root, buf,
  1526 + (struct ext4_extent_header *)
  1527 + inode->b.blocks.dir_blocks,
  1528 + fileblock, log2_blksz);
  1529 + if (!ext_block) {
  1530 + printf("invalid extent block\n");
  1531 + free(buf);
  1532 + return -EINVAL;
  1533 + }
1585 1534  
1586   - node = ext4fs_extent_cache_get(fileblock);
1587   - if (!node) {
1588   - printf("Extent Error\n");
1589   - return -1;
  1535 + extent = (struct ext4_extent *)(ext_block + 1);
  1536 +
  1537 + do {
  1538 + i++;
  1539 + if (i >= le16_to_cpu(ext_block->eh_entries))
  1540 + break;
  1541 + } while (fileblock >= le32_to_cpu(extent[i].ee_block));
  1542 + if (--i >= 0) {
  1543 + fileblock -= le32_to_cpu(extent[i].ee_block);
  1544 + if (fileblock >= le16_to_cpu(extent[i].ee_len)) {
  1545 + free(buf);
  1546 + return 0;
  1547 + }
  1548 +
  1549 + start = le16_to_cpu(extent[i].ee_start_hi);
  1550 + start = (start << 32) +
  1551 + le32_to_cpu(extent[i].ee_start_lo);
  1552 + free(buf);
  1553 + return fileblock + start;
1590 1554 }
1591 1555  
1592   - return fileblock - node->block + node->start;
  1556 + printf("Extent Error\n");
  1557 + free(buf);
  1558 + return -1;
1593 1559 }
1594 1560  
1595 1561 /* Direct blocks. */
fs/ext4/ext4_common.h
... ... @@ -57,9 +57,6 @@
57 57 int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name,
58 58 struct ext2fs_node **fnode, int *ftype);
59 59  
60   -int ext4fs_build_extent_cache(struct ext2_inode *inode);
61   -void ext4fs_free_extent_cache(void);
62   -
63 60 #if defined(CONFIG_EXT4_WRITE)
64 61 uint32_t ext4fs_div_roundup(uint32_t size, uint32_t n);
65 62 int ext4fs_checksum_update(unsigned int i);
... ... @@ -63,14 +63,6 @@
63 63 char *delayed_buf = NULL;
64 64 short status;
65 65  
66   - if (le32_to_cpu(node->inode.flags) & EXT4_EXTENTS_FL) {
67   - if (ext4fs_build_extent_cache(&node->inode)) {
68   - printf("Error building extent cache!\n");
69   - len = -1;
70   - goto out_exit;
71   - }
72   - }
73   -
74 66 /* Adjust len so it we can't read past the end of the file. */
75 67 if (len > filesize)
76 68 len = filesize;
... ... @@ -83,10 +75,8 @@
83 75 int blockend = blocksize;
84 76 int skipfirst = 0;
85 77 blknr = read_allocated_block(&(node->inode), i);
86   - if (blknr < 0) {
87   - len = -1;
88   - goto out_exit;
89   - }
  78 + if (blknr < 0)
  79 + return -1;
90 80  
91 81 blknr = blknr << log2_fs_blocksize;
92 82  
... ... @@ -116,10 +106,8 @@
116 106 delayed_skipfirst,
117 107 delayed_extent,
118 108 delayed_buf);
119   - if (status == 0) {
120   - len = -1;
121   - goto out_exit;
122   - }
  109 + if (status == 0)
  110 + return -1;
123 111 previous_block_number = blknr;
124 112 delayed_start = blknr;
125 113 delayed_extent = blockend;
... ... @@ -144,10 +132,8 @@
144 132 delayed_skipfirst,
145 133 delayed_extent,
146 134 delayed_buf);
147   - if (status == 0) {
148   - len = -1;
149   - goto out_exit;
150   - }
  135 + if (status == 0)
  136 + return -1;
151 137 previous_block_number = -1;
152 138 }
153 139 memset(buf, 0, blocksize - skipfirst);
154 140  
... ... @@ -159,16 +145,10 @@
159 145 status = ext4fs_devread(delayed_start,
160 146 delayed_skipfirst, delayed_extent,
161 147 delayed_buf);
162   - if (status == 0) {
163   - len = -1;
164   - goto out_exit;
165   - }
  148 + if (status == 0)
  149 + return -1;
166 150 previous_block_number = -1;
167 151 }
168   -
169   -
170   -out_exit:
171   - ext4fs_free_extent_cache();
172 152  
173 153 return len;
174 154 }