kern/144732: [patch] geom_cache erroneously decodes its on-disk
label
Eugene Grosbein
eugen at grosbein.pp.ru
Sun Mar 14 11:30:08 UTC 2010
>Number: 144732
>Category: kern
>Synopsis: [patch] geom_cache erroneously decodes its on-disk label
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Sun Mar 14 11:30:05 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator: Eugene Grosbein
>Release: FreeBSD 8.0-STABLE i386
>Organization:
RDTC JSC
>Environment:
System: FreeBSD grosbein.pp.ru 8.0-STABLE FreeBSD 8.0-STABLE #11: Sat Feb 6 21:23:34 KRAT 2010 root at grosbein.pp.ru:/usr/local/obj/usr/local/src/sys/DADV i386
>Description:
Let's take a look at struct g_cache_metadata definition in
/usr/src/sys/geom/cache/g_cache.h:
struct g_cache_metadata {
char md_magic[16]; /* Magic value. */
uint32_t md_version; /* Version number. */
char md_name[16]; /* Cache value. */
uint32_t md_bsize; /* Cache block size. */
uint32_t md_size; /* Cache size. */
uint64_t md_provsize; /* Provider's size. */
};
Note that md_size is 32-bit unsigned value. Next lines present
cache_metadata_encode() funtion that uses le32enc() to encode
this value, that's right.
Now look at cache_metadata_decode() below: it uses le16dec()
function to decode stored label. This error effectively limits
cache size to 16-bit quantity (and limits stripe/block size too).
>How-To-Repeat:
kldload geom_cache
gcache label -v -b 32768 -s 65536
Label is written successfully but gem_cache compains to kernel log:
GEOM_CACHE: Invalid size for device ca0.
That's because le16dec() decodes 65536 as zero cache size.
>Fix:
--- sys/geom/cache/g_cache.h.orig 2010-03-14 17:36:16.000000000 +0700
+++ sys/geom/cache/g_cache.h 2010-03-14 17:35:25.000000000 +0700
@@ -139,7 +139,7 @@
md->md_version = le32dec(data + 16);
bcopy(data + 20, md->md_name, sizeof(md->md_name));
md->md_bsize = le32dec(data + 36);
- md->md_size = le16dec(data + 40);
+ md->md_size = le32dec(data + 40);
md->md_provsize = le64dec(data + 44);
}
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list