forked from pool/ocfs2-tools
Accepting request 136016 from network:ha-clustering:Factory
bnc#781122 - fsck.ocfs2: fix inf loop in group desc check (forwarded request 135944 from yan_gao) OBS-URL: https://build.opensuse.org/request/show/136016 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/ocfs2-tools?expand=0&rev=44
This commit is contained in:
commit
e8c3e1bff6
68
0001-fswreck-Create-a-loop-in-group-chains.patch
Normal file
68
0001-fswreck-Create-a-loop-in-group-chains.patch
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
From 57a0a528f35d2b540d4ed533b6274586056664ce Mon Sep 17 00:00:00 2001
|
||||||
|
From: Goldwyn Rodrigues <rgoldwyn@suse.de>
|
||||||
|
Date: Thu, 20 Sep 2012 19:39:17 -0500
|
||||||
|
Subject: [PATCH 1/2] fswreck: Create a loop in group chains
|
||||||
|
|
||||||
|
---
|
||||||
|
fswreck/corrupt.c | 3 +++
|
||||||
|
fswreck/group.c | 6 ++++++
|
||||||
|
fswreck/include/fsck_type.h | 1 +
|
||||||
|
fswreck/main.c | 2 ++
|
||||||
|
4 files changed, 12 insertions(+)
|
||||||
|
|
||||||
|
Index: ocfs2-tools/fswreck/corrupt.c
|
||||||
|
===================================================================
|
||||||
|
--- ocfs2-tools.orig/fswreck/corrupt.c 2012-08-24 10:02:19.000000000 -0500
|
||||||
|
+++ ocfs2-tools/fswreck/corrupt.c 2012-09-25 11:12:35.000000000 -0500
|
||||||
|
@@ -331,6 +331,9 @@ void corrupt_group_desc(ocfs2_filesys *f
|
||||||
|
case GROUP_FREE_BITS:
|
||||||
|
func = mess_up_group_minor;
|
||||||
|
break;
|
||||||
|
+ case GROUP_CHAIN_LOOP:
|
||||||
|
+ func = mess_up_group_minor;
|
||||||
|
+ break;
|
||||||
|
case GROUP_GEN:
|
||||||
|
func = mess_up_group_gen;
|
||||||
|
break;
|
||||||
|
Index: ocfs2-tools/fswreck/group.c
|
||||||
|
===================================================================
|
||||||
|
--- ocfs2-tools.orig/fswreck/group.c 2012-08-24 10:02:19.000000000 -0500
|
||||||
|
+++ ocfs2-tools/fswreck/group.c 2012-09-25 11:12:35.000000000 -0500
|
||||||
|
@@ -176,6 +176,12 @@ static void damage_group_desc(ocfs2_file
|
||||||
|
bg->bg_chain, (bg->bg_chain + 10));
|
||||||
|
bg->bg_chain += 10;
|
||||||
|
break;
|
||||||
|
+ case GROUP_CHAIN_LOOP:
|
||||||
|
+ fprintf(stdout, "Corrput GROUP_LOOP: "
|
||||||
|
+ "change group next from %"PRIu64" to %"PRIu64"\n",
|
||||||
|
+ bg->bg_next_group, cr->c_blkno);
|
||||||
|
+ bg->bg_next_group = cpu_to_le64(cr->c_blkno);
|
||||||
|
+ break;
|
||||||
|
case GROUP_FREE_BITS:
|
||||||
|
fprintf(stdout, "Corrput GROUP_FREE_BITS: "
|
||||||
|
"change group free bits from %u to %u\n",
|
||||||
|
Index: ocfs2-tools/fswreck/include/fsck_type.h
|
||||||
|
===================================================================
|
||||||
|
--- ocfs2-tools.orig/fswreck/include/fsck_type.h 2012-08-24 10:02:19.000000000 -0500
|
||||||
|
+++ ocfs2-tools/fswreck/include/fsck_type.h 2012-09-25 11:12:35.000000000 -0500
|
||||||
|
@@ -57,6 +57,7 @@ enum fsck_type
|
||||||
|
GROUP_BLKNO,
|
||||||
|
GROUP_CHAIN,
|
||||||
|
GROUP_FREE_BITS,
|
||||||
|
+ GROUP_CHAIN_LOOP,
|
||||||
|
CHAIN_COUNT,
|
||||||
|
CHAIN_NEXT_FREE,
|
||||||
|
CHAIN_EMPTY,
|
||||||
|
Index: ocfs2-tools/fswreck/main.c
|
||||||
|
===================================================================
|
||||||
|
--- ocfs2-tools.orig/fswreck/main.c 2012-08-24 10:02:19.000000000 -0500
|
||||||
|
+++ ocfs2-tools/fswreck/main.c 2012-09-25 11:12:35.000000000 -0500
|
||||||
|
@@ -102,6 +102,8 @@ static struct prompt_code prompt_codes[N
|
||||||
|
"Corrupt chain group's blkno"),
|
||||||
|
define_prompt_code(GROUP_CHAIN, corrupt_group_desc, "", 1,
|
||||||
|
"Corrupt chain group's chain where it was in"),
|
||||||
|
+ define_prompt_code(GROUP_CHAIN_LOOP, corrupt_group_desc, "", 1,
|
||||||
|
+ "Corrupt group's chain to form a loop"),
|
||||||
|
define_prompt_code(GROUP_FREE_BITS, corrupt_group_desc, "", 1,
|
||||||
|
"Corrupt chain group's free bits"),
|
||||||
|
define_prompt_code(CHAIN_COUNT, corrupt_sys_file, "", 1,
|
156
0002-Break-a-chain-loop-in-group-desc.patch
Normal file
156
0002-Break-a-chain-loop-in-group-desc.patch
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
From 16f191550058a768935cab2fe575c48e64eba334 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Goldwyn Rodrigues <rgoldwyn@suse.de>
|
||||||
|
Date: Thu, 20 Sep 2012 20:12:14 -0500
|
||||||
|
Subject: [PATCH 2/2] Break a chain loop in group desc
|
||||||
|
|
||||||
|
This patch detects and a loop by checking hops against the theoretical
|
||||||
|
limit of number of chains in a chain_rec. If a loop is found, it breaks
|
||||||
|
it by storing the block numbers and comparing with exiting block
|
||||||
|
numbers.
|
||||||
|
---
|
||||||
|
fsck.ocfs2/fsck.ocfs2.checks.8.in | 9 ++++++
|
||||||
|
fsck.ocfs2/pass0.c | 61 ++++++++++++++++++++++++++++++++++---
|
||||||
|
include/ocfs2-kernel/ocfs2_fs.h | 2 +-
|
||||||
|
3 files changed, 67 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
Index: ocfs2-tools/fsck.ocfs2/fsck.ocfs2.checks.8.in
|
||||||
|
===================================================================
|
||||||
|
--- ocfs2-tools.orig/fsck.ocfs2/fsck.ocfs2.checks.8.in 2012-09-25 11:12:57.000000000 -0500
|
||||||
|
+++ ocfs2-tools/fsck.ocfs2/fsck.ocfs2.checks.8.in 2012-09-25 11:13:03.000000000 -0500
|
||||||
|
@@ -202,6 +202,15 @@ valid in its bitmap.
|
||||||
|
Answering yes decreases the number of recorded free bits so that it equals
|
||||||
|
the total number of bits in the group descriptor's bitmap.
|
||||||
|
|
||||||
|
+.SS "GROUP_CHAIN_LOOP"
|
||||||
|
+A chain may loop if the next field of the group descriptor points to one of
|
||||||
|
+the previous group descriptors in the chain. This causes the ocfs2 code, both
|
||||||
|
+user space and kernel module to loop forever.
|
||||||
|
+
|
||||||
|
+Answering yes breaks the loop at an optimum location so that all the existing
|
||||||
|
+group descriptors are in the chain. However, it cannot re-connect stray group
|
||||||
|
+descriptors and must rely on the rest of the fsck code to fix it.
|
||||||
|
+
|
||||||
|
.SS "CHAIN_COUNT"
|
||||||
|
The chain list embedded in an inode is limited by the block size and the
|
||||||
|
number of bytes consumed by the rest of the inode. A chain list header was
|
||||||
|
Index: ocfs2-tools/fsck.ocfs2/pass0.c
|
||||||
|
===================================================================
|
||||||
|
--- ocfs2-tools.orig/fsck.ocfs2/pass0.c 2012-09-25 11:12:57.000000000 -0500
|
||||||
|
+++ ocfs2-tools/fsck.ocfs2/pass0.c 2012-09-25 11:13:03.000000000 -0500
|
||||||
|
@@ -666,6 +666,46 @@ out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static errcode_t break_loop(o2fsck_state *ost, struct ocfs2_chain_rec *chain,
|
||||||
|
+ unsigned int max_depth)
|
||||||
|
+{
|
||||||
|
+ uint64_t *list;
|
||||||
|
+ int i;
|
||||||
|
+ unsigned int depth = 0;
|
||||||
|
+ uint64_t blkno = chain->c_blkno;
|
||||||
|
+ char *buf;
|
||||||
|
+ struct ocfs2_group_desc *gd;
|
||||||
|
+ errcode_t ret = ocfs2_malloc0(sizeof(uint64_t) * max_depth, &list);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto out;
|
||||||
|
+ ret = ocfs2_malloc_block(ost->ost_fs->fs_io, &buf);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto out;
|
||||||
|
+ gd = (struct ocfs2_group_desc *)buf;
|
||||||
|
+
|
||||||
|
+ while (blkno && (depth<=max_depth)) {
|
||||||
|
+ list[depth++] = blkno;
|
||||||
|
+ ret = ocfs2_read_group_desc(ost->ost_fs, blkno, buf);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto out;
|
||||||
|
+ blkno = gd->bg_next_group;
|
||||||
|
+ for (i=0; i<depth; i++)
|
||||||
|
+ if (list[i]==blkno) {
|
||||||
|
+ gd->bg_next_group = 0;
|
||||||
|
+ verbosef("Breaking gd loop %"PRIu64"\n", blkno);
|
||||||
|
+ ret = ocfs2_write_group_desc(ost->ost_fs,
|
||||||
|
+ blkno, buf);
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+out:
|
||||||
|
+ if (list)
|
||||||
|
+ ocfs2_free(&list);
|
||||||
|
+ if (buf)
|
||||||
|
+ ocfs2_free(&buf);
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* this takes a slightly ridiculous number of arguments :/ */
|
||||||
|
static errcode_t check_chain(o2fsck_state *ost,
|
||||||
|
struct ocfs2_dinode *di,
|
||||||
|
@@ -675,7 +715,8 @@ static errcode_t check_chain(o2fsck_stat
|
||||||
|
char *buf2,
|
||||||
|
int *chain_changed,
|
||||||
|
ocfs2_bitmap *allowed,
|
||||||
|
- ocfs2_bitmap *forbidden)
|
||||||
|
+ ocfs2_bitmap *forbidden,
|
||||||
|
+ unsigned int max_depth)
|
||||||
|
{
|
||||||
|
struct ocfs2_group_desc *bg1 = (struct ocfs2_group_desc *)buf1;
|
||||||
|
struct ocfs2_group_desc *bg2 = (struct ocfs2_group_desc *)buf2;
|
||||||
|
@@ -792,6 +833,14 @@ static errcode_t check_chain(o2fsck_stat
|
||||||
|
/* the loop will now start by reading bg1->next_group */
|
||||||
|
memcpy(buf1, buf2, ost->ost_fs->fs_blocksize);
|
||||||
|
depth++;
|
||||||
|
+ if (depth > max_depth) {
|
||||||
|
+ if (prompt(ost, PY, PR_GROUP_CHAIN_LOOP,
|
||||||
|
+ "Loop detected in chain %d at block %"PRIu64
|
||||||
|
+ ". Break the loop?",cs->cs_chain_no,
|
||||||
|
+ (uint64_t) chain->c_blkno))
|
||||||
|
+ ret = break_loop(ost, chain, max_depth);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we hit the premature end of a chain.. clear the last
|
||||||
|
@@ -854,6 +903,7 @@ static errcode_t verify_chain_alloc(o2fs
|
||||||
|
int changed = 0, trust_next_free = 1;
|
||||||
|
errcode_t ret = 0;
|
||||||
|
uint64_t chain_bytes;
|
||||||
|
+ unsigned int num_gds, max_chain_len;
|
||||||
|
|
||||||
|
if (memcmp(di->i_signature, OCFS2_INODE_SIGNATURE,
|
||||||
|
strlen(OCFS2_INODE_SIGNATURE))) {
|
||||||
|
@@ -883,9 +933,12 @@ static errcode_t verify_chain_alloc(o2fs
|
||||||
|
/* XXX should we check suballoc_node? */
|
||||||
|
|
||||||
|
cl = &di->id2.i_chain;
|
||||||
|
+ num_gds = (di->i_clusters + cl->cl_cpg)/cl->cl_cpg;
|
||||||
|
+ max_chain_len = (num_gds + cl->cl_count)/cl->cl_count;
|
||||||
|
|
||||||
|
- verbosef("cl cpg %u bpc %u count %u next %u\n",
|
||||||
|
- cl->cl_cpg, cl->cl_bpc, cl->cl_count, cl->cl_next_free_rec);
|
||||||
|
+ verbosef("cl cpg %u bpc %u count %u next %u gds %u max_ch_len %u\n",
|
||||||
|
+ cl->cl_cpg, cl->cl_bpc, cl->cl_count, cl->cl_next_free_rec,
|
||||||
|
+ num_gds, max_chain_len);
|
||||||
|
|
||||||
|
max_count = ocfs2_chain_recs_per_inode(ost->ost_fs->fs_blocksize);
|
||||||
|
|
||||||
|
@@ -948,7 +1001,7 @@ static errcode_t verify_chain_alloc(o2fs
|
||||||
|
.cs_cpg = cl->cl_cpg,
|
||||||
|
};
|
||||||
|
ret = check_chain(ost, di, &cs, cr, buf1, buf2, &changed,
|
||||||
|
- allowed, forbidden);
|
||||||
|
+ allowed, forbidden, max_chain_len);
|
||||||
|
/* XXX what? not checking ret? */
|
||||||
|
|
||||||
|
if (cr->c_blkno != 0) {
|
||||||
|
Index: ocfs2-tools/include/ocfs2-kernel/ocfs2_fs.h
|
||||||
|
===================================================================
|
||||||
|
--- ocfs2-tools.orig/include/ocfs2-kernel/ocfs2_fs.h 2012-09-25 11:12:57.000000000 -0500
|
||||||
|
+++ ocfs2-tools/include/ocfs2-kernel/ocfs2_fs.h 2012-09-25 11:13:03.000000000 -0500
|
||||||
|
@@ -1685,7 +1685,7 @@ static inline int ocfs2_sprintf_system_i
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ocfs2_set_de_type(struct ocfs2_dir_entry *de,
|
||||||
|
- umode_t mode)
|
||||||
|
+ unsigned short mode)
|
||||||
|
{
|
||||||
|
de->file_type = ocfs2_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
|
||||||
|
}
|
@ -1,3 +1,9 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Tue Sep 25 11:24:55 CDT 2012 - rgoldwyn@suse.de
|
||||||
|
|
||||||
|
- Fix infinite loop while checking for group desc chains
|
||||||
|
(bnc#781122)
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Fri Aug 24 12:12:32 CDT 2012 - rgoldwyn@suse.de
|
Fri Aug 24 12:12:32 CDT 2012 - rgoldwyn@suse.de
|
||||||
|
|
||||||
|
@ -52,6 +52,8 @@ Patch204: dont-use-var-lock-subsys.patch
|
|||||||
Patch205: ocfs2-tools-kernel33.patch
|
Patch205: ocfs2-tools-kernel33.patch
|
||||||
Patch206: ocfs2-tools-resource.patch
|
Patch206: ocfs2-tools-resource.patch
|
||||||
Patch207: fix-indexed-dirs.patch
|
Patch207: fix-indexed-dirs.patch
|
||||||
|
Patch208: 0001-fswreck-Create-a-loop-in-group-chains.patch
|
||||||
|
Patch209: 0002-Break-a-chain-loop-in-group-desc.patch
|
||||||
Url: http://oss.oracle.com/projects/ocfs2-tools/
|
Url: http://oss.oracle.com/projects/ocfs2-tools/
|
||||||
Requires: /sbin/chkconfig
|
Requires: /sbin/chkconfig
|
||||||
Requires: e2fsprogs
|
Requires: e2fsprogs
|
||||||
@ -129,6 +131,8 @@ managing the file system.
|
|||||||
%patch205 -p1
|
%patch205 -p1
|
||||||
%patch206 -p1
|
%patch206 -p1
|
||||||
%patch207 -p1
|
%patch207 -p1
|
||||||
|
%patch208 -p1
|
||||||
|
%patch209 -p1
|
||||||
|
|
||||||
%build
|
%build
|
||||||
export CFLAGS="${CFLAGS} ${RPM_OPT_FLAGS}"
|
export CFLAGS="${CFLAGS} ${RPM_OPT_FLAGS}"
|
||||||
|
Loading…
Reference in New Issue
Block a user