Commit 19bf1c2c7b9f21b9fe86315c5758d26c3049c2ad

Authored by Linus Torvalds

Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4

Pull ext4 bugfixes from Ted Ts'o:
 "Fixes for 3.11-rc2, sent at 5pm, in the professoinal style.  :-)"

I'm not sure I like this new level of "professionalism".
9-5, people, 9-5.

* tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
  ext4: call ext4_es_lru_add() after handling cache miss
  ext4: yield during large unlinks
  ext4: make the extent_status code more robust against ENOMEM failures
  ext4: simplify calculation of blocks to free on error
  ext4: fix error handling in ext4_ext_truncate()

Showing 3 changed files Side-by-side Diff

... ... @@ -2835,6 +2835,9 @@
2835 2835 err = -EIO;
2836 2836 break;
2837 2837 }
  2838 + /* Yield here to deal with large extent trees.
  2839 + * Should be a no-op if we did IO above. */
  2840 + cond_resched();
2838 2841 if (WARN_ON(i + 1 > depth)) {
2839 2842 err = -EIO;
2840 2843 break;
... ... @@ -4261,8 +4264,8 @@
4261 4264 /* not a good idea to call discard here directly,
4262 4265 * but otherwise we'd need to call it every free() */
4263 4266 ext4_discard_preallocations(inode);
4264   - ext4_free_blocks(handle, inode, NULL, ext4_ext_pblock(&newex),
4265   - ext4_ext_get_actual_len(&newex), fb_flags);
  4267 + ext4_free_blocks(handle, inode, NULL, newblock,
  4268 + EXT4_C2B(sbi, allocated_clusters), fb_flags);
4266 4269 goto out2;
4267 4270 }
4268 4271  
... ... @@ -4382,8 +4385,9 @@
4382 4385 }
4383 4386  
4384 4387 out3:
4385   - trace_ext4_ext_map_blocks_exit(inode, flags, map, err ? err : allocated);
4386   -
  4388 + trace_ext4_ext_map_blocks_exit(inode, flags, map,
  4389 + err ? err : allocated);
  4390 + ext4_es_lru_add(inode);
4387 4391 return err ? err : allocated;
4388 4392 }
4389 4393  
4390 4394  
4391 4395  
... ... @@ -4405,9 +4409,20 @@
4405 4409  
4406 4410 last_block = (inode->i_size + sb->s_blocksize - 1)
4407 4411 >> EXT4_BLOCK_SIZE_BITS(sb);
  4412 +retry:
4408 4413 err = ext4_es_remove_extent(inode, last_block,
4409 4414 EXT_MAX_BLOCKS - last_block);
  4415 + if (err == ENOMEM) {
  4416 + cond_resched();
  4417 + congestion_wait(BLK_RW_ASYNC, HZ/50);
  4418 + goto retry;
  4419 + }
  4420 + if (err) {
  4421 + ext4_std_error(inode->i_sb, err);
  4422 + return;
  4423 + }
4410 4424 err = ext4_ext_remove_space(inode, last_block, EXT_MAX_BLOCKS - 1);
  4425 + ext4_std_error(inode->i_sb, err);
4411 4426 }
4412 4427  
4413 4428 static void ext4_falloc_update_inode(struct inode *inode,
fs/ext4/extents_status.c
... ... @@ -148,6 +148,8 @@
148 148 ext4_lblk_t end);
149 149 static int __es_try_to_reclaim_extents(struct ext4_inode_info *ei,
150 150 int nr_to_scan);
  151 +static int __ext4_es_shrink(struct ext4_sb_info *sbi, int nr_to_scan,
  152 + struct ext4_inode_info *locked_ei);
151 153  
152 154 int __init ext4_init_es(void)
153 155 {
154 156  
... ... @@ -665,7 +667,13 @@
665 667 err = __es_remove_extent(inode, lblk, end);
666 668 if (err != 0)
667 669 goto error;
  670 +retry:
668 671 err = __es_insert_extent(inode, &newes);
  672 + if (err == -ENOMEM && __ext4_es_shrink(EXT4_SB(inode->i_sb), 1,
  673 + EXT4_I(inode)))
  674 + goto retry;
  675 + if (err == -ENOMEM && !ext4_es_is_delayed(&newes))
  676 + err = 0;
669 677  
670 678 error:
671 679 write_unlock(&EXT4_I(inode)->i_es_lock);
672 680  
... ... @@ -744,8 +752,10 @@
744 752 struct extent_status orig_es;
745 753 ext4_lblk_t len1, len2;
746 754 ext4_fsblk_t block;
747   - int err = 0;
  755 + int err;
748 756  
  757 +retry:
  758 + err = 0;
749 759 es = __es_tree_search(&tree->root, lblk);
750 760 if (!es)
751 761 goto out;
... ... @@ -780,6 +790,10 @@
780 790 if (err) {
781 791 es->es_lblk = orig_es.es_lblk;
782 792 es->es_len = orig_es.es_len;
  793 + if ((err == -ENOMEM) &&
  794 + __ext4_es_shrink(EXT4_SB(inode->i_sb), 1,
  795 + EXT4_I(inode)))
  796 + goto retry;
783 797 goto out;
784 798 }
785 799 } else {
786 800  
787 801  
788 802  
... ... @@ -889,22 +903,14 @@
889 903 return -1;
890 904 }
891 905  
892   -static int ext4_es_shrink(struct shrinker *shrink, struct shrink_control *sc)
  906 +static int __ext4_es_shrink(struct ext4_sb_info *sbi, int nr_to_scan,
  907 + struct ext4_inode_info *locked_ei)
893 908 {
894   - struct ext4_sb_info *sbi = container_of(shrink,
895   - struct ext4_sb_info, s_es_shrinker);
896 909 struct ext4_inode_info *ei;
897 910 struct list_head *cur, *tmp;
898 911 LIST_HEAD(skiped);
899   - int nr_to_scan = sc->nr_to_scan;
900 912 int ret, nr_shrunk = 0;
901 913  
902   - ret = percpu_counter_read_positive(&sbi->s_extent_cache_cnt);
903   - trace_ext4_es_shrink_enter(sbi->s_sb, nr_to_scan, ret);
904   -
905   - if (!nr_to_scan)
906   - return ret;
907   -
908 914 spin_lock(&sbi->s_es_lru_lock);
909 915  
910 916 /*
... ... @@ -933,7 +939,7 @@
933 939 continue;
934 940 }
935 941  
936   - if (ei->i_es_lru_nr == 0)
  942 + if (ei->i_es_lru_nr == 0 || ei == locked_ei)
937 943 continue;
938 944  
939 945 write_lock(&ei->i_es_lock);
... ... @@ -951,6 +957,27 @@
951 957 /* Move the newer inodes into the tail of the LRU list. */
952 958 list_splice_tail(&skiped, &sbi->s_es_lru);
953 959 spin_unlock(&sbi->s_es_lru_lock);
  960 +
  961 + if (locked_ei && nr_shrunk == 0)
  962 + nr_shrunk = __es_try_to_reclaim_extents(ei, nr_to_scan);
  963 +
  964 + return nr_shrunk;
  965 +}
  966 +
  967 +static int ext4_es_shrink(struct shrinker *shrink, struct shrink_control *sc)
  968 +{
  969 + struct ext4_sb_info *sbi = container_of(shrink,
  970 + struct ext4_sb_info, s_es_shrinker);
  971 + int nr_to_scan = sc->nr_to_scan;
  972 + int ret, nr_shrunk;
  973 +
  974 + ret = percpu_counter_read_positive(&sbi->s_extent_cache_cnt);
  975 + trace_ext4_es_shrink_enter(sbi->s_sb, nr_to_scan, ret);
  976 +
  977 + if (!nr_to_scan)
  978 + return ret;
  979 +
  980 + nr_shrunk = __ext4_es_shrink(sbi, nr_to_scan, NULL);
954 981  
955 982 ret = percpu_counter_read_positive(&sbi->s_extent_cache_cnt);
956 983 trace_ext4_es_shrink_exit(sbi->s_sb, nr_shrunk, ret);
... ... @@ -514,10 +514,9 @@
514 514 "logical block %lu\n", inode->i_ino, flags, map->m_len,
515 515 (unsigned long) map->m_lblk);
516 516  
517   - ext4_es_lru_add(inode);
518   -
519 517 /* Lookup extent status tree firstly */
520 518 if (ext4_es_lookup_extent(inode, map->m_lblk, &es)) {
  519 + ext4_es_lru_add(inode);
521 520 if (ext4_es_is_written(&es) || ext4_es_is_unwritten(&es)) {
522 521 map->m_pblk = ext4_es_pblock(&es) +
523 522 map->m_lblk - es.es_lblk;
524 523  
... ... @@ -1529,11 +1528,9 @@
1529 1528 "logical block %lu\n", inode->i_ino, map->m_len,
1530 1529 (unsigned long) map->m_lblk);
1531 1530  
1532   - ext4_es_lru_add(inode);
1533   -
1534 1531 /* Lookup extent status tree firstly */
1535 1532 if (ext4_es_lookup_extent(inode, iblock, &es)) {
1536   -
  1533 + ext4_es_lru_add(inode);
1537 1534 if (ext4_es_is_hole(&es)) {
1538 1535 retval = 0;
1539 1536 down_read((&EXT4_I(inode)->i_data_sem));