Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 360470
b: refs/heads/master
c: 242e18c
h: refs/heads/master
v: v3
  • Loading branch information
Chris Mason committed Feb 1, 2013
1 parent 167d95b commit c29ce7a
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8de972b4faa4be9b2a3c53103e18d86092a5da45
refs/heads/master: 242e18c7c1a8ff3aa05c9fbb6e0bb427511152a6
16 changes: 16 additions & 0 deletions trunk/fs/btrfs/extent_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -4184,6 +4184,7 @@ static inline void btrfs_release_extent_buffer(struct extent_buffer *eb)

static void check_buffer_tree_ref(struct extent_buffer *eb)
{
int refs;
/* the ref bit is tricky. We have to make sure it is set
* if we have the buffer dirty. Otherwise the
* code to free a buffer can end up dropping a dirty
Expand All @@ -4204,6 +4205,10 @@ static void check_buffer_tree_ref(struct extent_buffer *eb)
* So bump the ref count first, then set the bit. If someone
* beat us to it, drop the ref we added.
*/
refs = atomic_read(&eb->refs);
if (refs >= 2 && test_bit(EXTENT_BUFFER_TREE_REF, &eb->bflags))
return;

spin_lock(&eb->refs_lock);
if (!test_and_set_bit(EXTENT_BUFFER_TREE_REF, &eb->bflags))
atomic_inc(&eb->refs);
Expand Down Expand Up @@ -4405,9 +4410,20 @@ static int release_extent_buffer(struct extent_buffer *eb, gfp_t mask)

void free_extent_buffer(struct extent_buffer *eb)
{
int refs;
int old;
if (!eb)
return;

while (1) {
refs = atomic_read(&eb->refs);
if (refs <= 3)
break;
old = atomic_cmpxchg(&eb->refs, refs, refs - 1);
if (old == refs)
return;
}

spin_lock(&eb->refs_lock);
if (atomic_read(&eb->refs) == 2 &&
test_bit(EXTENT_BUFFER_DUMMY, &eb->bflags))
Expand Down

0 comments on commit c29ce7a

Please sign in to comment.