]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] buffer_head leak
authorAlexander Viro <viro@math.psu.edu>
Mon, 22 Apr 2002 05:59:14 +0000 (22:59 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Mon, 22 Apr 2002 05:59:14 +0000 (22:59 -0700)
Fix buffer-head leak on truncate race.

The reason why it hadn't been triggered left right and center is that we
step on that path only when partial truncate blows away an indirect
block shared between truncated and remaining areas _and_ races with
ext2_get_block() in the beginning of said area.  IOW, we need

* indirect block with hole in the beginning
* get_block starting to read that block
* truncate killing everything past the hole (and thus freeing indirect
  block in question)
* get_block completing the read and noticing that block is actually
  gone.

OK...  IMO we should do that brelse() outside of the loop.

fs/ext2/inode.c
fs/ext3/inode.c
fs/minix/itree_common.c
fs/sysv/itree.c

index ec6cb41079f76fc48af20b353651f47c5ae6f080..26a0f74cab9be0fb31d6f3238a91566e2dbd1dc3 100644 (file)
@@ -261,6 +261,7 @@ static Indirect *ext2_get_branch(struct inode *inode,
 
 changed:
        read_unlock(&EXT2_I(inode)->i_meta_lock);
+       brelse(bh);
        *err = -EAGAIN;
        goto no_block;
 failure:
index 19048b5d80d51679f94ad2163203cc95067f25e3..6218acef217207695941cb1161d9dd560a25d20f 100644 (file)
@@ -414,6 +414,7 @@ static Indirect *ext3_get_branch(struct inode *inode, int depth, int *offsets,
        return NULL;
 
 changed:
+       brelse(bh);
        *err = -EAGAIN;
        goto no_block;
 failure:
index 692f3043090a9f7dae805bae18c000f40f661a41..8bd0f1a826fd47c4550d28b3442dcca0e1ed7afe 100644 (file)
@@ -57,6 +57,7 @@ static inline Indirect *get_branch(struct inode *inode,
 
 changed:
        read_unlock(&pointers_lock);
+       brelse(bh);
        *err = -EAGAIN;
        goto no_block;
 failure:
index f86495440b42484828b780a2cd610e1f48452245..74476c196b0fcf4a8f0acdeda5e6df19c33a4bf7 100644 (file)
@@ -108,6 +108,7 @@ static Indirect *get_branch(struct inode *inode,
        return NULL;
 
 changed:
+       brelse(bh);
        *err = -EAGAIN;
        goto no_block;
 failure: