diff options
| author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2019-10-23 12:02:47 +0200 | 
|---|---|---|
| committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2019-10-23 12:10:05 +0200 | 
| commit | 2e79e22e092acd55da0b2db066e4826d7d152c41 (patch) | |
| tree | e7ec9782c0b7831c511af711424126a2b9a4eb07 /fs/btrfs/file.c | |
| parent | f1b4a9217efd61d0b84c6dc404596c8519ff6f59 (diff) | |
| parent | 7d194c2100ad2a6dded545887d02754948ca5241 (diff) | |
Merge v5.4-rc4 into drm-next
Thierry needs fd70c7755bf0 ("drm/bridge: tc358767: fix max_tu_symbol
value") to be able to merge his dp_link patch series.
Some adjacent changes conflicts, plus some clashes in i915 due to
cherry-picking and git trying to be helpful and leaving both versions
in.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'fs/btrfs/file.c')
| -rw-r--r-- | fs/btrfs/file.c | 13 | 
1 files changed, 12 insertions, 1 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 8fe4eb7e5045..27e5b269e729 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1591,7 +1591,6 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,  	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);  	struct btrfs_root *root = BTRFS_I(inode)->root;  	struct page **pages = NULL; -	struct extent_state *cached_state = NULL;  	struct extent_changeset *data_reserved = NULL;  	u64 release_bytes = 0;  	u64 lockstart; @@ -1611,6 +1610,7 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,  		return -ENOMEM;  	while (iov_iter_count(i) > 0) { +		struct extent_state *cached_state = NULL;  		size_t offset = offset_in_page(pos);  		size_t sector_offset;  		size_t write_bytes = min(iov_iter_count(i), @@ -1758,9 +1758,20 @@ again:  		if (copied > 0)  			ret = btrfs_dirty_pages(inode, pages, dirty_pages,  						pos, copied, &cached_state); + +		/* +		 * If we have not locked the extent range, because the range's +		 * start offset is >= i_size, we might still have a non-NULL +		 * cached extent state, acquired while marking the extent range +		 * as delalloc through btrfs_dirty_pages(). Therefore free any +		 * possible cached extent state to avoid a memory leak. +		 */  		if (extents_locked)  			unlock_extent_cached(&BTRFS_I(inode)->io_tree,  					     lockstart, lockend, &cached_state); +		else +			free_extent_state(cached_state); +  		btrfs_delalloc_release_extents(BTRFS_I(inode), reserve_bytes,  					       true);  		if (ret) {  | 
