Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 332539
b: refs/heads/master
c: b9a8cc5
h: refs/heads/master
i:
  332537: c458709
  332535: 577fe5d
v: v3
  • Loading branch information
Miao Xie authored and Chris Mason committed Oct 1, 2012
1 parent fb2a273 commit 66eee99
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 45 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 361048f586f59d414421c6486dd846063a0cac98
refs/heads/master: b9a8cc5bef963b76c5b6c3016b7e91988a3e758b
62 changes: 18 additions & 44 deletions trunk/fs/btrfs/ordered-data.c
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,6 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
struct btrfs_ordered_inode_tree *tree = &BTRFS_I(inode)->ordered_tree;
u64 disk_i_size;
u64 new_i_size;
u64 i_size_test;
u64 i_size = i_size_read(inode);
struct rb_node *node;
struct rb_node *prev = NULL;
Expand Down Expand Up @@ -835,55 +834,30 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
break;
if (test->file_offset >= i_size)
break;
if (test->file_offset >= disk_i_size)
if (test->file_offset >= disk_i_size) {
/*
* we don't update disk_i_size now, so record this
* undealt i_size. Or we will not know the real
* i_size.
*/
if (test->outstanding_isize < offset)
test->outstanding_isize = offset;
if (ordered &&
ordered->outstanding_isize >
test->outstanding_isize)
test->outstanding_isize =
ordered->outstanding_isize;
goto out;
}
new_i_size = min_t(u64, offset, i_size);

/*
* at this point, we know we can safely update i_size to at least
* the offset from this ordered extent. But, we need to
* walk forward and see if ios from higher up in the file have
* finished.
*/
if (ordered) {
node = rb_next(&ordered->rb_node);
} else {
if (prev)
node = rb_next(prev);
else
node = rb_first(&tree->tree);
}

/*
* We are looking for an area between our current extent and the next
* ordered extent to update the i_size to. There are 3 cases here
*
* 1) We don't actually have anything and we can update to i_size.
* 2) We have stuff but they already did their i_size update so again we
* can just update to i_size.
* 3) We have an outstanding ordered extent so the most we can update
* our disk_i_size to is the start of the next offset.
*/
i_size_test = i_size;
for (; node; node = rb_next(node)) {
test = rb_entry(node, struct btrfs_ordered_extent, rb_node);

if (test_bit(BTRFS_ORDERED_UPDATED_ISIZE, &test->flags))
continue;
if (test->file_offset > offset) {
i_size_test = test->file_offset;
break;
}
}
new_i_size = min_t(u64, offset, i_size);

/*
* i_size_test is the end of a region after this ordered
* extent where there are no ordered extents, we can safely set
* disk_i_size to this.
* Some ordered extents may completed before the current one, and
* we hold the real i_size in ->outstanding_isize.
*/
if (i_size_test > offset)
new_i_size = min_t(u64, i_size_test, i_size);
if (ordered && ordered->outstanding_isize > new_i_size)
new_i_size = min_t(u64, ordered->outstanding_isize, i_size);
BTRFS_I(inode)->disk_i_size = new_i_size;
ret = 0;
out:
Expand Down
7 changes: 7 additions & 0 deletions trunk/fs/btrfs/ordered-data.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,13 @@ struct btrfs_ordered_extent {
/* number of bytes that still need writing */
u64 bytes_left;

/*
* the end of the ordered extent which is behind it but
* didn't update disk_i_size. Please see the comment of
* btrfs_ordered_update_i_size();
*/
u64 outstanding_isize;

/* flags (described above) */
unsigned long flags;

Expand Down

0 comments on commit 66eee99

Please sign in to comment.