Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 27c9d772 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull btrfs fixes from Chris Mason:
 "This has a few fixes from Filipe, along with a readdir fix from Dave
  that we've been testing for some time"

* 'for-linus-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
  btrfs: properly set the termination value of ctx->pos in readdir
  Btrfs: fix hang on extent buffer lock caused by the inode_paths ioctl
  Btrfs: remove no longer used function extent_read_full_page_nolock()
  Btrfs: fix page reading in extent_same ioctl leading to csum errors
  Btrfs: fix invalid page accesses in extent_same (dedup) ioctl
parents dfc85286 bc4ef759
Loading
Loading
Loading
Loading
+6 −4
Original line number Original line Diff line number Diff line
@@ -1406,6 +1406,7 @@ char *btrfs_ref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,
			read_extent_buffer(eb, dest + bytes_left,
			read_extent_buffer(eb, dest + bytes_left,
					   name_off, name_len);
					   name_off, name_len);
		if (eb != eb_in) {
		if (eb != eb_in) {
			if (!path->skip_locking)
				btrfs_tree_read_unlock_blocking(eb);
				btrfs_tree_read_unlock_blocking(eb);
			free_extent_buffer(eb);
			free_extent_buffer(eb);
		}
		}
@@ -1426,9 +1427,10 @@ char *btrfs_ref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,
		eb = path->nodes[0];
		eb = path->nodes[0];
		/* make sure we can use eb after releasing the path */
		/* make sure we can use eb after releasing the path */
		if (eb != eb_in) {
		if (eb != eb_in) {
			atomic_inc(&eb->refs);
			if (!path->skip_locking)
			btrfs_tree_read_lock(eb);
				btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK);
				btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK);
			path->nodes[0] = NULL;
			path->locks[0] = 0;
		}
		}
		btrfs_release_path(path);
		btrfs_release_path(path);
		iref = btrfs_item_ptr(eb, slot, struct btrfs_inode_ref);
		iref = btrfs_item_ptr(eb, slot, struct btrfs_inode_ref);
+1 −5
Original line number Original line Diff line number Diff line
@@ -637,10 +637,6 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
	faili = nr_pages - 1;
	faili = nr_pages - 1;
	cb->nr_pages = nr_pages;
	cb->nr_pages = nr_pages;


	/* In the parent-locked case, we only locked the range we are
	 * interested in.  In all other cases, we can opportunistically
	 * cache decompressed data that goes beyond the requested range. */
	if (!(bio_flags & EXTENT_BIO_PARENT_LOCKED))
	add_ra_bio_pages(inode, em_start + em_len, cb);
	add_ra_bio_pages(inode, em_start + em_len, cb);


	/* include any pages we added in add_ra-bio_pages */
	/* include any pages we added in add_ra-bio_pages */
+2 −1
Original line number Original line Diff line number Diff line
@@ -1689,7 +1689,7 @@ int btrfs_should_delete_dir_index(struct list_head *del_list,
 *
 *
 */
 */
int btrfs_readdir_delayed_dir_index(struct dir_context *ctx,
int btrfs_readdir_delayed_dir_index(struct dir_context *ctx,
				    struct list_head *ins_list)
				    struct list_head *ins_list, bool *emitted)
{
{
	struct btrfs_dir_item *di;
	struct btrfs_dir_item *di;
	struct btrfs_delayed_item *curr, *next;
	struct btrfs_delayed_item *curr, *next;
@@ -1733,6 +1733,7 @@ int btrfs_readdir_delayed_dir_index(struct dir_context *ctx,


		if (over)
		if (over)
			return 1;
			return 1;
		*emitted = true;
	}
	}
	return 0;
	return 0;
}
}
+1 −1
Original line number Original line Diff line number Diff line
@@ -144,7 +144,7 @@ void btrfs_put_delayed_items(struct list_head *ins_list,
int btrfs_should_delete_dir_index(struct list_head *del_list,
int btrfs_should_delete_dir_index(struct list_head *del_list,
				  u64 index);
				  u64 index);
int btrfs_readdir_delayed_dir_index(struct dir_context *ctx,
int btrfs_readdir_delayed_dir_index(struct dir_context *ctx,
				    struct list_head *ins_list);
				    struct list_head *ins_list, bool *emitted);


/* for init */
/* for init */
int __init btrfs_delayed_inode_init(void);
int __init btrfs_delayed_inode_init(void);
+11 −34
Original line number Original line Diff line number Diff line
@@ -2897,12 +2897,11 @@ static int __do_readpage(struct extent_io_tree *tree,
	struct block_device *bdev;
	struct block_device *bdev;
	int ret;
	int ret;
	int nr = 0;
	int nr = 0;
	int parent_locked = *bio_flags & EXTENT_BIO_PARENT_LOCKED;
	size_t pg_offset = 0;
	size_t pg_offset = 0;
	size_t iosize;
	size_t iosize;
	size_t disk_io_size;
	size_t disk_io_size;
	size_t blocksize = inode->i_sb->s_blocksize;
	size_t blocksize = inode->i_sb->s_blocksize;
	unsigned long this_bio_flag = *bio_flags & EXTENT_BIO_PARENT_LOCKED;
	unsigned long this_bio_flag = 0;


	set_page_extent_mapped(page);
	set_page_extent_mapped(page);


@@ -2942,7 +2941,6 @@ static int __do_readpage(struct extent_io_tree *tree,
			kunmap_atomic(userpage);
			kunmap_atomic(userpage);
			set_extent_uptodate(tree, cur, cur + iosize - 1,
			set_extent_uptodate(tree, cur, cur + iosize - 1,
					    &cached, GFP_NOFS);
					    &cached, GFP_NOFS);
			if (!parent_locked)
			unlock_extent_cached(tree, cur,
			unlock_extent_cached(tree, cur,
					     cur + iosize - 1,
					     cur + iosize - 1,
					     &cached, GFP_NOFS);
					     &cached, GFP_NOFS);
@@ -2952,7 +2950,6 @@ static int __do_readpage(struct extent_io_tree *tree,
				      end - cur + 1, get_extent, em_cached);
				      end - cur + 1, get_extent, em_cached);
		if (IS_ERR_OR_NULL(em)) {
		if (IS_ERR_OR_NULL(em)) {
			SetPageError(page);
			SetPageError(page);
			if (!parent_locked)
			unlock_extent(tree, cur, end);
			unlock_extent(tree, cur, end);
			break;
			break;
		}
		}
@@ -3038,9 +3035,6 @@ static int __do_readpage(struct extent_io_tree *tree,


			set_extent_uptodate(tree, cur, cur + iosize - 1,
			set_extent_uptodate(tree, cur, cur + iosize - 1,
					    &cached, GFP_NOFS);
					    &cached, GFP_NOFS);
			if (parent_locked)
				free_extent_state(cached);
			else
			unlock_extent_cached(tree, cur,
			unlock_extent_cached(tree, cur,
					     cur + iosize - 1,
					     cur + iosize - 1,
					     &cached, GFP_NOFS);
					     &cached, GFP_NOFS);
@@ -3052,7 +3046,6 @@ static int __do_readpage(struct extent_io_tree *tree,
		if (test_range_bit(tree, cur, cur_end,
		if (test_range_bit(tree, cur, cur_end,
				   EXTENT_UPTODATE, 1, NULL)) {
				   EXTENT_UPTODATE, 1, NULL)) {
			check_page_uptodate(tree, page);
			check_page_uptodate(tree, page);
			if (!parent_locked)
			unlock_extent(tree, cur, cur + iosize - 1);
			unlock_extent(tree, cur, cur + iosize - 1);
			cur = cur + iosize;
			cur = cur + iosize;
			pg_offset += iosize;
			pg_offset += iosize;
@@ -3063,7 +3056,6 @@ static int __do_readpage(struct extent_io_tree *tree,
		 */
		 */
		if (block_start == EXTENT_MAP_INLINE) {
		if (block_start == EXTENT_MAP_INLINE) {
			SetPageError(page);
			SetPageError(page);
			if (!parent_locked)
			unlock_extent(tree, cur, cur + iosize - 1);
			unlock_extent(tree, cur, cur + iosize - 1);
			cur = cur + iosize;
			cur = cur + iosize;
			pg_offset += iosize;
			pg_offset += iosize;
@@ -3083,7 +3075,6 @@ static int __do_readpage(struct extent_io_tree *tree,
			*bio_flags = this_bio_flag;
			*bio_flags = this_bio_flag;
		} else {
		} else {
			SetPageError(page);
			SetPageError(page);
			if (!parent_locked)
			unlock_extent(tree, cur, cur + iosize - 1);
			unlock_extent(tree, cur, cur + iosize - 1);
		}
		}
		cur = cur + iosize;
		cur = cur + iosize;
@@ -3213,20 +3204,6 @@ int extent_read_full_page(struct extent_io_tree *tree, struct page *page,
	return ret;
	return ret;
}
}


int extent_read_full_page_nolock(struct extent_io_tree *tree, struct page *page,
				 get_extent_t *get_extent, int mirror_num)
{
	struct bio *bio = NULL;
	unsigned long bio_flags = EXTENT_BIO_PARENT_LOCKED;
	int ret;

	ret = __do_readpage(tree, page, get_extent, NULL, &bio, mirror_num,
			    &bio_flags, READ, NULL);
	if (bio)
		ret = submit_one_bio(READ, bio, mirror_num, bio_flags);
	return ret;
}

static noinline void update_nr_written(struct page *page,
static noinline void update_nr_written(struct page *page,
				      struct writeback_control *wbc,
				      struct writeback_control *wbc,
				      unsigned long nr_written)
				      unsigned long nr_written)
Loading