summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2013-07-16 10:28:47 -0400
committerTheodore Ts'o <tytso@mit.edu>2013-07-16 10:28:47 -0400
commit63b999685cb372e24eb73f255cd73547026370fd (patch)
tree92053ac3ca2fa7ba351fce31d558ba13cc37926d
parent76828c882630ced08b5ddce22cc0095b05de9bc5 (diff)
downloadlinux-63b999685cb372e24eb73f255cd73547026370fd.tar.gz
linux-63b999685cb372e24eb73f255cd73547026370fd.tar.bz2
linux-63b999685cb372e24eb73f255cd73547026370fd.zip
ext4: call ext4_es_lru_add() after handling cache miss
If there are no items in the extent status tree, ext4_es_lru_add() is a no-op. So it is not sufficient to call ext4_es_lru_add() before we try to lookup an entry in the extent status tree. We also need to call it at the end of ext4_ext_map_blocks(), after items have been added to the extent status tree. This could lead to inodes with that have extent status trees but which are not in the LRU list, which means they won't get considered for eviction by the es_shrinker. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> Cc: Zheng Liu <wenqing.lz@taobao.com> Cc: stable@vger.kernel.org
-rw-r--r--fs/ext4/extents.c5
-rw-r--r--fs/ext4/inode.c7
2 files changed, 5 insertions, 7 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index cfdc51e30257..a61873808f76 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -4385,8 +4385,9 @@ out2:
}
out3:
- trace_ext4_ext_map_blocks_exit(inode, flags, map, err ? err : allocated);
-
+ trace_ext4_ext_map_blocks_exit(inode, flags, map,
+ err ? err : allocated);
+ ext4_es_lru_add(inode);
return err ? err : allocated;
}
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 98b9bff92a8a..ba33c67d6e48 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -514,10 +514,9 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
"logical block %lu\n", inode->i_ino, flags, map->m_len,
(unsigned long) map->m_lblk);
- ext4_es_lru_add(inode);
-
/* Lookup extent status tree firstly */
if (ext4_es_lookup_extent(inode, map->m_lblk, &es)) {
+ ext4_es_lru_add(inode);
if (ext4_es_is_written(&es) || ext4_es_is_unwritten(&es)) {
map->m_pblk = ext4_es_pblock(&es) +
map->m_lblk - es.es_lblk;
@@ -1529,11 +1528,9 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock,
"logical block %lu\n", inode->i_ino, map->m_len,
(unsigned long) map->m_lblk);
- ext4_es_lru_add(inode);
-
/* Lookup extent status tree firstly */
if (ext4_es_lookup_extent(inode, iblock, &es)) {
-
+ ext4_es_lru_add(inode);
if (ext4_es_is_hole(&es)) {
retval = 0;
down_read((&EXT4_I(inode)->i_data_sem));