Skip to content

Commit

Permalink
patch snapshot_merge_oops_fix.patch
Browse files Browse the repository at this point in the history
  • Loading branch information
Amir Goldstein committed Jun 14, 2010
1 parent b6145a1 commit 4404f3e
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 40 deletions.
47 changes: 22 additions & 25 deletions fs/next3/inode.c
Expand Up @@ -3058,7 +3058,7 @@ static Indirect *next3_find_shared(struct inode *inode, int depth,
* @pblocks: pointer to counter of branch blocks
*
* If @pblocks is not NULL, don't free blocks, only update blocks counter and
* mark blocks in exclude bitmap.
* test that blocks are excluded.
*/
static void next3_clear_blocks_cow(handle_t *handle, struct inode *inode,
struct buffer_head *bh, next3_fsblk_t block_to_free,
Expand All @@ -3072,9 +3072,17 @@ static void next3_clear_blocks(handle_t *handle, struct inode *inode,
{
__le32 *p;
#ifdef CONFIG_NEXT3_FS_SNAPSHOT_CLEANUP
if (pblocks)
/* we're not actually deleting any blocks */
bh = NULL;

if (pblocks) {
/* test that blocks are excluded and update blocks counter */
next3_snapshot_test_excluded(handle, inode, block_to_free,
count);
if (is_handle_aborted(handle))
return;
*pblocks += count;
return;
}

#endif
if (try_to_extend_transaction(handle, inode)) {
if (bh) {
Expand All @@ -3098,18 +3106,6 @@ static void next3_clear_blocks(handle_t *handle, struct inode *inode,
}
}

#ifdef CONFIG_NEXT3_FS_SNAPSHOT_CLEANUP
if (pblocks) {
/* mark blocks excluded and update blocks counter */
next3_snapshot_get_clear_access(handle, inode, block_to_free,
count);
if (is_handle_aborted(handle))
return;
*pblocks += count;
return;
}

#endif
/*
* Any buffers which are on the journal will be in memory. We find
* them on the hash table so journal_revoke() will run journal_forget()
Expand Down Expand Up @@ -3165,7 +3161,7 @@ static void next3_clear_blocks(handle_t *handle, struct inode *inode,
* @pblocks: pointer to counter of branch blocks
*
* If @pblocks is not NULL, don't free blocks, only update blocks counter and
* mark blocks in exclude bitmap.
* test that blocks are excluded.
*/
static void next3_free_data_cow(handle_t *handle, struct inode *inode,
struct buffer_head *this_bh,
Expand Down Expand Up @@ -3305,7 +3301,7 @@ static void next3_free_data(handle_t *handle, struct inode *inode,
* @pblocks: pointer to counter of branch blocks
*
* If @pblocks is not NULL, don't free blocks, only update blocks counter
* and mark blocks in exclude bitmap.
* and test that blocks are excluded.
*/
void next3_free_branches_cow(handle_t *handle, struct inode *inode,
struct buffer_head *parent_bh,
Expand Down Expand Up @@ -3412,15 +3408,11 @@ static void next3_free_branches(handle_t *handle, struct inode *inode,
*/
if (is_handle_aborted(handle))
return;
if (try_to_extend_transaction(handle, inode)) {
next3_mark_inode_dirty(handle, inode);
next3_journal_test_restart(handle, inode);
}

#ifdef CONFIG_NEXT3_FS_SNAPSHOT_CLEANUP
if (pblocks) {
/* mark block excluded and update counter */
next3_snapshot_get_clear_access(handle, inode,
/* test that block is excluded and update
blocks counter */
next3_snapshot_test_excluded(handle, inode,
nr, 1);
if (is_handle_aborted(handle))
return;
Expand All @@ -3429,6 +3421,11 @@ static void next3_free_branches(handle_t *handle, struct inode *inode,
}

#endif
if (try_to_extend_transaction(handle, inode)) {
next3_mark_inode_dirty(handle, inode);
next3_journal_test_restart(handle, inode);
}

next3_free_blocks(handle, inode, nr, 1);

if (parent_bh) {
Expand Down
33 changes: 27 additions & 6 deletions fs/next3/snapshot.c
Expand Up @@ -697,14 +697,21 @@ next3_snapshot_test_cow_bitmap(handle_t *handle, struct inode *snapshot,

#ifdef CONFIG_NEXT3_FS_SNAPSHOT_EXCLUDE_BITMAP
/*
* next3_snapshot_exclude_blocks() marks blocks in exclude bitmap
* next3_snapshot_test_and_exclude() marks blocks in exclude bitmap
* @where: name of caller function
* @handle: JBD handle
* @sb: super block handle
* @block: address of first block to exclude
* @maxblocks: max. blocks to exclude
* @exclude: if false, return -EIO if block needs to be excluded
*
* Return values:
* >= 0 - no. of blocks set in exclude bitmap
* < 0 - error
*/
int next3_snapshot_exclude_blocks(handle_t *handle, struct super_block *sb,
next3_fsblk_t block, int maxblocks)
int next3_snapshot_test_and_exclude(const char *where, handle_t *handle,
struct super_block *sb, next3_fsblk_t block, int maxblocks,
int exclude)
{
struct buffer_head *exclude_bitmap_bh = NULL;
unsigned long block_group = SNAPSHOT_BLOCK_GROUP(block);
Expand All @@ -716,15 +723,18 @@ int next3_snapshot_exclude_blocks(handle_t *handle, struct super_block *sb,
if (!exclude_bitmap_bh)
return 0;

err = next3_journal_get_write_access(handle, exclude_bitmap_bh);
if (exclude)
err = next3_journal_get_write_access(handle, exclude_bitmap_bh);
if (err)
return err;
goto out;

while (count > 0 && bit < SNAPSHOT_BLOCKS_PER_GROUP) {
if (!next3_set_bit_atomic(sb_bgl_lock(NEXT3_SB(sb),
block_group),
bit, exclude_bitmap_bh->b_data)) {
n++;
if (!exclude)
break;
} else if (n) {
snapshot_debug(2, "excluded blocks: [%d-%d/%ld]\n",
bit-n, bit-1, block_group);
Expand All @@ -735,16 +745,27 @@ int next3_snapshot_exclude_blocks(handle_t *handle, struct super_block *sb,
count--;
}

if (n && !exclude) {
NEXT3_SET_FLAGS(sb, NEXT3_FLAGS_FIX_EXCLUDE);
next3_error(sb, where,
"snapshot file block [%d/%lu] not in exclude bitmap! - "
"running fsck to fix exclude bitmap is recommended.\n",
bit, block_group);
err = -EIO;
goto out;
}

if (n) {
snapshot_debug(2, "excluded blocks: [%d-%d/%ld]\n",
bit-n, bit-1, block_group);
excluded += n;
}

if (excluded) {
if (exclude && excluded) {
err = next3_journal_dirty_metadata(handle, exclude_bitmap_bh);
trace_cow_add(handle, excluded, excluded);
}
out:
brelse(exclude_bitmap_bh);
return err ? err : excluded;
}
Expand Down
30 changes: 21 additions & 9 deletions fs/next3/snapshot.h
Expand Up @@ -20,7 +20,7 @@
#include "snapshot_debug.h"


#define NEXT3_SNAPSHOT_VERSION "next3 snapshot v1.0.11 (7-Jun-2010)"
#define NEXT3_SNAPSHOT_VERSION "next3 snapshot v1.0.11-1 (14-Jun-2010)"

/*
* use signed 64bit for snapshot image addresses
Expand Down Expand Up @@ -299,21 +299,33 @@ static inline int next3_snapshot_get_delete_access(handle_t *handle,

#endif
#ifdef CONFIG_NEXT3_FS_SNAPSHOT_CLEANUP
extern int next3_snapshot_exclude_blocks(handle_t *handle,
struct super_block *sb, next3_fsblk_t block, int maxblocks);
extern int next3_snapshot_test_and_exclude(const char *where, handle_t *handle,
struct super_block *sb, next3_fsblk_t block, int maxblocks,
int exclude);

/*
* get_clear_access() - mark snapshot blocks excluded
* next3_snapshot_exclude_blocks() - exclude snapshot blocks
*
* Called from next3_snapshot_test_and_{cow,move}() when copying/moving
* blocks to active snapshot.
*
* On error handle is aborted.
*/
#define next3_snapshot_exclude_blocks(handle, sb, block, count) \
next3_snapshot_test_and_exclude(__func__, (handle), (sb), \
(block), (count), 1)

/*
* next3_snapshot_test_excluded() - test that snapshot blocks are excluded
*
* Called from next3_snapshot_clean(), next3_free_branches_cow() and
* next3_clear_blocks_cow() under snapshot_mutex.
*
* On error handle is aborted.
*/
static inline void next3_snapshot_get_clear_access(handle_t *handle,
struct inode *inode, next3_fsblk_t block, int count)
{
next3_snapshot_exclude_blocks(handle, inode->i_sb, block, count);
}
#define next3_snapshot_test_excluded(handle, inode, block, count) \
next3_snapshot_test_and_exclude(__func__, (handle), (inode)->i_sb, \
(block), (count), 0)

#endif
#ifdef CONFIG_NEXT3_FS_SNAPSHOT_RACE_READ
Expand Down

0 comments on commit 4404f3e

Please sign in to comment.