Permalink
Browse files

Fix the hole detection bug of mdsl ITB gc.

  • Loading branch information...
1 parent 1b7bc3b commit 7bba589b66645ea9b129ce0f0b7988f9150d207b @macan committed Dec 15, 2011
Showing with 80 additions and 16 deletions.
  1. +47 −3 mdsl/gc.c
  2. +33 −13 test/mdsl/gc.c
View
@@ -3,7 +3,7 @@
* <macan@ncic.ac.cn>
*
* Armed with EMACS.
- * Time-stamp: <2011-06-27 22:28:27 macan>
+ * Time-stamp: <2011-12-15 10:10:07 macan>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -76,6 +76,44 @@ int itb_gc_append(int gen, struct itb *itb, struct itb_info *ii)
return err;
}
+/* __is_hole() detect holes in ITB file
+ *
+ * Rational:
+ * 1. if itb->h is ALL zero, it is a hole
+ * 2. if itb->h is PART zero, and across a page border, it is a hole
+ */
+int __is_hole(u64 offset, struct itb *itb)
+{
+ if (!atomic_read(&itb->h.len) ||
+ itb->h.depth == 0 ||
+ itb->h.adepth == 0)
+ return 1;
+ else {
+ /* check if the itbheader is INTEGRATED */
+ u64 size = offset & (getpagesize() - 1);
+
+ if (size >= sizeof(itb->h))
+ return 0;
+
+ if (offsetof(struct itbh, len) < size) {
+ return 0;
+ } else if (offsetof(struct itbh, depth) < size) {
+ return 0;
+ } else {
+ /* blind detect! */
+ if (itb->h.flag > ITB_SNAPSHOT)
+ return 1;
+ if (itb->h.adepth != ITB_DEPTH)
+ return 1;
+ if (atomic_read(&itb->h.len) >
+ sizeof(struct itb) + sizeof(struct ite) * ITB_SIZE)
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
/* do GC-TX on itb file change
*
* write the tx_begin in hmo.storage.gc_fd
@@ -422,7 +460,12 @@ int mdsl_gc_md_round(u64 duuid, int master, struct fdhash_entry *md,
hvfs_err(mdsl, "fd read failed w/ %d\n", err);
goto out_free;
}
- if (!atomic_read(&itb->h.len)) {
+ /* BUG-xxx: how to determine the ITB border?
+ *
+ * The page hole might be in range 1-4095 bytes, we need a always
+ * correct way to detect holes.
+ */
+ if (__is_hole(offset, itb)) {
/* we should seek to next active page! */
u64 last_offset;
@@ -604,7 +647,8 @@ int mdsl_gc_md(u64 duuid)
last_offset = gc_offset;
redo_round:
- hvfs_warning(mdsl, "GC directory %lx in round %d\n", duuid, round++);
+ hvfs_warning(mdsl, "GC directory %lx in round %d from off %lx\n",
+ duuid, round++, gc_offset);
err = mdsl_gc_md_round(duuid, master, fde, itbf, &gc_offset);
if (err < 0) {
hvfs_err(mdsl, "GC metadata in stage %d's round %d failed w/ %d\n",
View
@@ -3,7 +3,7 @@
* <macan@ncic.ac.cn>
*
* Armed with EMACS.
- * Time-stamp: <2011-05-10 17:29:34 macan>
+ * Time-stamp: <2011-12-15 10:13:01 macan>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -117,6 +117,11 @@ void *racer(void *arg)
/* try to append more itb to the itb file */
len = lib_random(range_end - range_begin) + range_begin;
atomic_set(&itb->h.len, len);
+ /* cheat hole detection */
+ itb->h.flag = ITB_ACTIVE;
+ itb->h.adepth = ITB_DEPTH;
+ itb->h.depth = 1;
+
itb->h.itbid = lib_random(0xfff);
itb->h.puuid = duuid;
@@ -190,28 +195,41 @@ int main(int argc, char *argv[])
{
u64 duuid = 1;
pthread_t racer_thread;
- int err = 0;
+ char *value;
+ int err = 0, sid = 0, start_racer;
hvfs_info(mdsl, "MDSL GC Unit Test ...\n");
- /* got the uuid from user */
- if (argc < 2) {
- hvfs_err(mdsl, "Usage: %s dir_uuid\n", argv[0]);
+ /* got the site_id, uuid from user */
+ if (argc < 3) {
+ hvfs_err(mdsl, "Usage: %s site_id dir_uuid\n", argv[0]);
return EINVAL;
} else {
- duuid = atol(argv[1]);
+ sid = atoi(argv[1]);
+ duuid = atol(argv[2]);
}
+
+ value = getenv("racer");
+ if (value) {
+ start_racer = atoi(value);
+ } else
+ start_racer = 0;
+ hvfs_info(mdsl, "Begin GC with RACER %s.\n",
+ start_racer ? "enabled(corrupt original file)" : "disable");
mdsl_init();
- hmo.site_id = HVFS_MDSL(0);
+ hmo.site_id = HVFS_MDSL(sid);
mdsl_verify();
preload_dir(duuid);
- /* start a racer */
- err = pthread_create(&racer_thread, NULL, &racer, (void *)duuid);
- if (err)
- goto out_clean;
+ /* start a racer */
+ if (start_racer) {
+ err = pthread_create(&racer_thread, NULL, &racer, (void *)duuid);
+ if (err)
+ goto out_clean;
+ }
+
sleep(5);
err = mdsl_gc_md(duuid);
if (err) {
@@ -220,8 +238,10 @@ int main(int argc, char *argv[])
goto out_clean;
}
- racer_stop = 1;
- pthread_join(racer_thread, NULL);
+ if (start_racer) {
+ racer_stop = 1;
+ pthread_join(racer_thread, NULL);
+ }
out_clean:
mdsl_destroy();

0 comments on commit 7bba589

Please sign in to comment.