]> Pileus Git - ~andy/linux/commitdiff
ext4: call ext4_es_lru_add() after handling cache miss
authorTheodore Ts'o <tytso@mit.edu>
Tue, 16 Jul 2013 14:28:47 +0000 (10:28 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 16 Jul 2013 14:28:47 +0000 (10:28 -0400)
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
fs/ext4/extents.c
fs/ext4/inode.c

index cfdc51e302575e7c57e7baf12d37ab0c53b6273d..a61873808f7659aafefa103f96f1f51f564ece04 100644 (file)
@@ -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;
 }
 
index 98b9bff92a8a2d0d42f290d21d5cd4000b6bdae8..ba33c67d6e48a8b035cc9113ce05b916c535350c 100644 (file)
@@ -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));