Skip to content

Commit bce19f9

Browse files
committed
Merge branch 'for-chris-4.12' of git://git.kernel.org/pub/scm/linux/kernel/git/fdmanana/linux into for-linus-4.12
2 parents c2a9c7a + a7e3b97 commit bce19f9

File tree

5 files changed

+277
-66
lines changed

5 files changed

+277
-66
lines changed

fs/btrfs/btrfs_inode.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,13 @@ struct btrfs_inode {
124124
*/
125125
u64 delalloc_bytes;
126126

127+
/*
128+
* Total number of bytes pending delalloc that fall within a file
129+
* range that is either a hole or beyond EOF (and no prealloc extent
130+
* exists in the range). This is always <= delalloc_bytes.
131+
*/
132+
u64 new_delalloc_bytes;
133+
127134
/*
128135
* total number of bytes pending defrag, used by stat to check whether
129136
* it needs COW.

fs/btrfs/extent_io.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,17 @@
1515
#define EXTENT_DEFRAG (1U << 6)
1616
#define EXTENT_BOUNDARY (1U << 9)
1717
#define EXTENT_NODATASUM (1U << 10)
18-
#define EXTENT_DO_ACCOUNTING (1U << 11)
18+
#define EXTENT_CLEAR_META_RESV (1U << 11)
1919
#define EXTENT_FIRST_DELALLOC (1U << 12)
2020
#define EXTENT_NEED_WAIT (1U << 13)
2121
#define EXTENT_DAMAGED (1U << 14)
2222
#define EXTENT_NORESERVE (1U << 15)
2323
#define EXTENT_QGROUP_RESERVED (1U << 16)
2424
#define EXTENT_CLEAR_DATA_RESV (1U << 17)
25+
#define EXTENT_DELALLOC_NEW (1U << 18)
2526
#define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK)
27+
#define EXTENT_DO_ACCOUNTING (EXTENT_CLEAR_META_RESV | \
28+
EXTENT_CLEAR_DATA_RESV)
2629
#define EXTENT_CTLBITS (EXTENT_DO_ACCOUNTING | EXTENT_FIRST_DELALLOC)
2730

2831
/*

fs/btrfs/file.c

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1404,6 +1404,47 @@ static noinline int prepare_pages(struct inode *inode, struct page **pages,
14041404

14051405
}
14061406

1407+
static int btrfs_find_new_delalloc_bytes(struct btrfs_inode *inode,
1408+
const u64 start,
1409+
const u64 len,
1410+
struct extent_state **cached_state)
1411+
{
1412+
u64 search_start = start;
1413+
const u64 end = start + len - 1;
1414+
1415+
while (search_start < end) {
1416+
const u64 search_len = end - search_start + 1;
1417+
struct extent_map *em;
1418+
u64 em_len;
1419+
int ret = 0;
1420+
1421+
em = btrfs_get_extent(inode, NULL, 0, search_start,
1422+
search_len, 0);
1423+
if (IS_ERR(em))
1424+
return PTR_ERR(em);
1425+
1426+
if (em->block_start != EXTENT_MAP_HOLE)
1427+
goto next;
1428+
1429+
em_len = em->len;
1430+
if (em->start < search_start)
1431+
em_len -= search_start - em->start;
1432+
if (em_len > search_len)
1433+
em_len = search_len;
1434+
1435+
ret = set_extent_bit(&inode->io_tree, search_start,
1436+
search_start + em_len - 1,
1437+
EXTENT_DELALLOC_NEW,
1438+
NULL, cached_state, GFP_NOFS);
1439+
next:
1440+
search_start = extent_map_end(em);
1441+
free_extent_map(em);
1442+
if (ret)
1443+
return ret;
1444+
}
1445+
return 0;
1446+
}
1447+
14071448
/*
14081449
* This function locks the extent and properly waits for data=ordered extents
14091450
* to finish before allowing the pages to be modified if need.
@@ -1432,8 +1473,11 @@ lock_and_cleanup_extent_if_need(struct btrfs_inode *inode, struct page **pages,
14321473
+ round_up(pos + write_bytes - start_pos,
14331474
fs_info->sectorsize) - 1;
14341475

1435-
if (start_pos < inode->vfs_inode.i_size) {
1476+
if (start_pos < inode->vfs_inode.i_size ||
1477+
(inode->flags & BTRFS_INODE_PREALLOC)) {
14361478
struct btrfs_ordered_extent *ordered;
1479+
unsigned int clear_bits;
1480+
14371481
lock_extent_bits(&inode->io_tree, start_pos, last_pos,
14381482
cached_state);
14391483
ordered = btrfs_lookup_ordered_range(inode, start_pos,
@@ -1454,11 +1498,19 @@ lock_and_cleanup_extent_if_need(struct btrfs_inode *inode, struct page **pages,
14541498
}
14551499
if (ordered)
14561500
btrfs_put_ordered_extent(ordered);
1457-
1501+
ret = btrfs_find_new_delalloc_bytes(inode, start_pos,
1502+
last_pos - start_pos + 1,
1503+
cached_state);
1504+
clear_bits = EXTENT_DIRTY | EXTENT_DELALLOC |
1505+
EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG;
1506+
if (ret)
1507+
clear_bits |= EXTENT_DELALLOC_NEW | EXTENT_LOCKED;
14581508
clear_extent_bit(&inode->io_tree, start_pos,
1459-
last_pos, EXTENT_DIRTY | EXTENT_DELALLOC |
1460-
EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
1461-
0, 0, cached_state, GFP_NOFS);
1509+
last_pos, clear_bits,
1510+
(clear_bits & EXTENT_LOCKED) ? 1 : 0,
1511+
0, cached_state, GFP_NOFS);
1512+
if (ret)
1513+
return ret;
14621514
*lockstart = start_pos;
14631515
*lockend = last_pos;
14641516
ret = 1;
@@ -2848,8 +2900,10 @@ static long btrfs_fallocate(struct file *file, int mode,
28482900
}
28492901
ret = btrfs_qgroup_reserve_data(inode, cur_offset,
28502902
last_byte - cur_offset);
2851-
if (ret < 0)
2903+
if (ret < 0) {
2904+
free_extent_map(em);
28522905
break;
2906+
}
28532907
} else {
28542908
/*
28552909
* Do not need to reserve unwritten extent for this

0 commit comments

Comments
 (0)