mirror of
https://github.com/versity/scoutfs.git
synced 2026-04-22 22:40:31 +00:00
Validate freed ref consistency in dirty_alloc_blocks
Add a WARN_ON_ONCE check that the freed list ref blkno matches the block header blkno after dirtying alloc blocks. Also save and restore freed.first_nr on the error path, and initialize av_old/fr_old to 0 so the diagnostic message has valid values. Signed-off-by: Auke Kok <auke.kok@versity.com>
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
#include "trans.h"
|
||||
#include "alloc.h"
|
||||
#include "counters.h"
|
||||
#include "msg.h"
|
||||
#include "scoutfs_trace.h"
|
||||
|
||||
/*
|
||||
@@ -496,10 +497,11 @@ static int dirty_alloc_blocks(struct super_block *sb,
|
||||
struct scoutfs_block *fr_bl = NULL;
|
||||
struct scoutfs_block *bl;
|
||||
bool link_orig = false;
|
||||
__le32 orig_first_nr;
|
||||
u64 av_peek;
|
||||
u64 av_old;
|
||||
u64 av_old = 0;
|
||||
u64 fr_peek;
|
||||
u64 fr_old;
|
||||
u64 fr_old = 0;
|
||||
int ret;
|
||||
|
||||
if (alloc->dirty_avail_bl != NULL)
|
||||
@@ -509,6 +511,7 @@ static int dirty_alloc_blocks(struct super_block *sb,
|
||||
|
||||
/* undo dirty freed if we get an error after */
|
||||
orig_freed = alloc->freed.ref;
|
||||
orig_first_nr = alloc->freed.first_nr;
|
||||
|
||||
if (alloc->dirty_avail_bl != NULL) {
|
||||
ret = 0;
|
||||
@@ -562,6 +565,17 @@ static int dirty_alloc_blocks(struct super_block *sb,
|
||||
/* sort dirty avail to encourage contiguous sorted meta blocks */
|
||||
list_block_sort(av_bl->data);
|
||||
|
||||
lblk = fr_bl->data;
|
||||
if (WARN_ON_ONCE(alloc->freed.ref.blkno != lblk->hdr.blkno)) {
|
||||
scoutfs_err(sb, "dirty_alloc freed ref %llu hdr %llu av_old %llu fr_old %llu av_peek %llu fr_peek %llu link_orig %d",
|
||||
le64_to_cpu(alloc->freed.ref.blkno),
|
||||
le64_to_cpu(lblk->hdr.blkno),
|
||||
av_old, fr_old, av_peek, fr_peek, link_orig);
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
lblk = NULL;
|
||||
|
||||
if (av_old)
|
||||
list_block_add(&alloc->freed, fr_bl->data, av_old);
|
||||
if (fr_old)
|
||||
@@ -578,6 +592,7 @@ out:
|
||||
if (fr_bl)
|
||||
scoutfs_block_writer_forget(sb, wri, fr_bl);
|
||||
alloc->freed.ref = orig_freed;
|
||||
alloc->freed.first_nr = orig_first_nr;
|
||||
}
|
||||
|
||||
mutex_unlock(&alloc->mutex);
|
||||
|
||||
Reference in New Issue
Block a user