OSDN Git Service

btrfs: sysfs: don't leak memory when failing add fsid
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / fs / btrfs / extent_io.c
index 9abe187..a18f558 100644 (file)
@@ -2534,7 +2534,7 @@ int end_extent_writepage(struct page *page, int err, u64 start, u64 end)
        if (!uptodate) {
                ClearPageUptodate(page);
                SetPageError(page);
-               ret = ret < 0 ? ret : -EIO;
+               ret = err < 0 ? err : -EIO;
                mapping_set_error(page->mapping, ret);
        }
        return 0;
@@ -2786,12 +2786,6 @@ struct bio *btrfs_bio_clone(struct bio *bio, gfp_t gfp_mask)
                btrfs_bio->csum = NULL;
                btrfs_bio->csum_allocated = NULL;
                btrfs_bio->end_io = NULL;
-
-#ifdef CONFIG_BLK_CGROUP
-               /* FIXME, put this into bio_clone_bioset */
-               if (bio->bi_css)
-                       bio_associate_blkcg(new, bio->bi_css);
-#endif
        }
        return new;
 }
@@ -3112,11 +3106,11 @@ static int __do_readpage(struct extent_io_tree *tree,
                 */
                if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags) &&
                    prev_em_start && *prev_em_start != (u64)-1 &&
-                   *prev_em_start != em->orig_start)
+                   *prev_em_start != em->start)
                        force_bio_submit = true;
 
                if (prev_em_start)
-                       *prev_em_start = em->orig_start;
+                       *prev_em_start = em->start;
 
                free_extent_map(em);
                em = NULL;
@@ -3853,8 +3847,10 @@ static noinline_for_stack int write_one_eb(struct extent_buffer *eb,
        struct block_device *bdev = fs_info->fs_devices->latest_bdev;
        struct extent_io_tree *tree = &BTRFS_I(fs_info->btree_inode)->io_tree;
        u64 offset = eb->start;
+       u32 nritems;
        unsigned long i, num_pages;
        unsigned long bio_flags = 0;
+       unsigned long start, end;
        int rw = (epd->sync_io ? WRITE_SYNC : WRITE) | REQ_META;
        int ret = 0;
 
@@ -3864,6 +3860,23 @@ static noinline_for_stack int write_one_eb(struct extent_buffer *eb,
        if (btrfs_header_owner(eb) == BTRFS_TREE_LOG_OBJECTID)
                bio_flags = EXTENT_BIO_TREE_LOG;
 
+       /* set btree blocks beyond nritems with 0 to avoid stale content. */
+       nritems = btrfs_header_nritems(eb);
+       if (btrfs_header_level(eb) > 0) {
+               end = btrfs_node_key_ptr_offset(nritems);
+
+               memset_extent_buffer(eb, 0, end, eb->len - end);
+       } else {
+               /*
+                * leaf:
+                * header 0 1 2 .. N ... data_N .. data_2 data_1 data_0
+                */
+               start = btrfs_item_nr_offset(nritems);
+               end = btrfs_leaf_data(eb) +
+                     leaf_data_end(fs_info->tree_root, eb);
+               memset_extent_buffer(eb, 0, start, end - start);
+       }
+
        for (i = 0; i < num_pages; i++) {
                struct page *p = eb->pages[i];
 
@@ -5300,11 +5313,20 @@ int read_extent_buffer_pages(struct extent_io_tree *tree,
                        lock_page(page);
                }
                locked_pages++;
+       }
+       /*
+        * We need to firstly lock all pages to make sure that
+        * the uptodate bit of our pages won't be affected by
+        * clear_extent_buffer_uptodate().
+        */
+       for (i = start_i; i < num_pages; i++) {
+               page = eb->pages[i];
                if (!PageUptodate(page)) {
                        num_reads++;
                        all_uptodate = 0;
                }
        }
+
        if (all_uptodate) {
                if (start_i == 0)
                        set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);
@@ -5359,9 +5381,8 @@ unlock_exit:
        return ret;
 }
 
-void read_extent_buffer(struct extent_buffer *eb, void *dstv,
-                       unsigned long start,
-                       unsigned long len)
+void read_extent_buffer(const struct extent_buffer *eb, void *dstv,
+                       unsigned long start, unsigned long len)
 {
        size_t cur;
        size_t offset;
@@ -5390,9 +5411,9 @@ void read_extent_buffer(struct extent_buffer *eb, void *dstv,
        }
 }
 
-int read_extent_buffer_to_user(struct extent_buffer *eb, void __user *dstv,
-                       unsigned long start,
-                       unsigned long len)
+int read_extent_buffer_to_user(const struct extent_buffer *eb,
+                              void __user *dstv,
+                              unsigned long start, unsigned long len)
 {
        size_t cur;
        size_t offset;
@@ -5427,10 +5448,10 @@ int read_extent_buffer_to_user(struct extent_buffer *eb, void __user *dstv,
        return ret;
 }
 
-int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start,
-                              unsigned long min_len, char **map,
-                              unsigned long *map_start,
-                              unsigned long *map_len)
+int map_private_extent_buffer(const struct extent_buffer *eb,
+                             unsigned long start, unsigned long min_len,
+                             char **map, unsigned long *map_start,
+                             unsigned long *map_len)
 {
        size_t offset = start & (PAGE_CACHE_SIZE - 1);
        char *kaddr;
@@ -5465,9 +5486,8 @@ int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start,
        return 0;
 }
 
-int memcmp_extent_buffer(struct extent_buffer *eb, const void *ptrv,
-                         unsigned long start,
-                         unsigned long len)
+int memcmp_extent_buffer(const struct extent_buffer *eb, const void *ptrv,
+                        unsigned long start, unsigned long len)
 {
        size_t cur;
        size_t offset;