Merge tag 'mmc-updates-for-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel...
[cascardo/linux.git] / fs / ext4 / mballoc.c
index 526e553..1bf6fe7 100644 (file)
@@ -1373,7 +1373,7 @@ static int mb_find_extent(struct ext4_buddy *e4b, int block,
        ex->fe_start += next;
 
        while (needed > ex->fe_len &&
-              (buddy = mb_find_buddy(e4b, order, &max))) {
+              mb_find_buddy(e4b, order, &max)) {
 
                if (block + 1 >= max)
                        break;
@@ -2607,9 +2607,17 @@ static void ext4_free_data_callback(struct super_block *sb,
        mb_debug(1, "gonna free %u blocks in group %u (0x%p):",
                 entry->efd_count, entry->efd_group, entry);
 
-       if (test_opt(sb, DISCARD))
-               ext4_issue_discard(sb, entry->efd_group,
-                                  entry->efd_start_cluster, entry->efd_count);
+       if (test_opt(sb, DISCARD)) {
+               err = ext4_issue_discard(sb, entry->efd_group,
+                                        entry->efd_start_cluster,
+                                        entry->efd_count);
+               if (err && err != -EOPNOTSUPP)
+                       ext4_msg(sb, KERN_WARNING, "discard request in"
+                                " group:%d block:%d count:%d failed"
+                                " with %d", entry->efd_group,
+                                entry->efd_start_cluster,
+                                entry->efd_count, err);
+       }
 
        err = ext4_mb_load_buddy(sb, entry->efd_group, &e4b);
        /* we expect to find existing buddy because it's pinned */
@@ -4310,8 +4318,10 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
 repeat:
                /* allocate space in core */
                *errp = ext4_mb_regular_allocator(ac);
-               if (*errp)
+               if (*errp) {
+                       ext4_discard_allocated_blocks(ac);
                        goto errout;
+               }
 
                /* as we've just preallocated more space than
                 * user requested orinally, we store allocated
@@ -4333,10 +4343,10 @@ repeat:
                        ac->ac_b_ex.fe_len = 0;
                        ac->ac_status = AC_STATUS_CONTINUE;
                        goto repeat;
-               } else if (*errp)
-               errout:
+               } else if (*errp) {
                        ext4_discard_allocated_blocks(ac);
-               else {
+                       goto errout;
+               } else {
                        block = ext4_grp_offs_to_block(sb, &ac->ac_b_ex);
                        ar->len = ac->ac_b_ex.fe_len;
                }
@@ -4347,6 +4357,7 @@ repeat:
                *errp = -ENOSPC;
        }
 
+errout:
        if (*errp) {
                ac->ac_b_ex.fe_len = 0;
                ar->len = 0;
@@ -4656,8 +4667,16 @@ do_more:
                 * with group lock held. generate_buddy look at
                 * them with group lock_held
                 */
-               if (test_opt(sb, DISCARD))
-                       ext4_issue_discard(sb, block_group, bit, count);
+               if (test_opt(sb, DISCARD)) {
+                       err = ext4_issue_discard(sb, block_group, bit, count);
+                       if (err && err != -EOPNOTSUPP)
+                               ext4_msg(sb, KERN_WARNING, "discard request in"
+                                        " group:%d block:%d count:%lu failed"
+                                        " with %d", block_group, bit, count,
+                                        err);
+               }
+
+
                ext4_lock_group(sb, block_group);
                mb_clear_bits(bitmap_bh->b_data, bit, count_clusters);
                mb_free_blocks(inode, &e4b, bit, count_clusters);
@@ -4851,10 +4870,11 @@ error_return:
  * one will allocate those blocks, mark it as used in buddy bitmap. This must
  * be called with under the group lock.
  */
-static void ext4_trim_extent(struct super_block *sb, int start, int count,
+static int ext4_trim_extent(struct super_block *sb, int start, int count,
                             ext4_group_t group, struct ext4_buddy *e4b)
 {
        struct ext4_free_extent ex;
+       int ret = 0;
 
        trace_ext4_trim_extent(sb, group, start, count);
 
@@ -4870,9 +4890,10 @@ static void ext4_trim_extent(struct super_block *sb, int start, int count,
         */
        mb_mark_used(e4b, &ex);
        ext4_unlock_group(sb, group);
-       ext4_issue_discard(sb, group, start, count);
+       ret = ext4_issue_discard(sb, group, start, count);
        ext4_lock_group(sb, group);
        mb_free_blocks(NULL, e4b, start, ex.fe_len);
+       return ret;
 }
 
 /**
@@ -4901,7 +4922,7 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group,
        void *bitmap;
        ext4_grpblk_t next, count = 0, free_count = 0;
        struct ext4_buddy e4b;
-       int ret;
+       int ret = 0;
 
        trace_ext4_trim_all_free(sb, group, start, max);
 
@@ -4928,8 +4949,11 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group,
                next = mb_find_next_bit(bitmap, max + 1, start);
 
                if ((next - start) >= minblocks) {
-                       ext4_trim_extent(sb, start,
-                                        next - start, group, &e4b);
+                       ret = ext4_trim_extent(sb, start,
+                                              next - start, group, &e4b);
+                       if (ret && ret != -EOPNOTSUPP)
+                               break;
+                       ret = 0;
                        count += next - start;
                }
                free_count += next - start;
@@ -4950,8 +4974,10 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group,
                        break;
        }
 
-       if (!ret)
+       if (!ret) {
+               ret = count;
                EXT4_MB_GRP_SET_TRIMMED(e4b.bd_info);
+       }
 out:
        ext4_unlock_group(sb, group);
        ext4_mb_unload_buddy(&e4b);
@@ -4959,7 +4985,7 @@ out:
        ext4_debug("trimmed %d blocks in the group %d\n",
                count, group);
 
-       return count;
+       return ret;
 }
 
 /**