ceph: fail gracefully on corrupt osdmap (bad pg_temp mapping)

Return an error and report a corrupt map instead of crying BUG().

Signed-off-by: Sage Weil <sage@newdream.net>
diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c
index e38fe630..342e5f8 100644
--- a/fs/ceph/osdmap.c
+++ b/fs/ceph/osdmap.c
@@ -366,8 +366,8 @@
 /*
  * Insert a new pg_temp mapping
  */
-static void __insert_pg_mapping(struct ceph_pg_mapping *new,
-				struct rb_root *root)
+static int __insert_pg_mapping(struct ceph_pg_mapping *new,
+			       struct rb_root *root)
 {
 	struct rb_node **p = &root->rb_node;
 	struct rb_node *parent = NULL;
@@ -381,11 +381,12 @@
 		else if (new->pgid > pg->pgid)
 			p = &(*p)->rb_right;
 		else
-			BUG();
+			return -EEXIST;
 	}
 
 	rb_link_node(&new->node, parent, p);
 	rb_insert_color(&new->node, root);
+	return 0;
 }
 
 /*
@@ -481,7 +482,9 @@
 		for (j = 0; j < n; j++)
 			ceph_decode_32(p, pg->osds[j]);
 
-		__insert_pg_mapping(pg, &map->pg_temp);
+		err = __insert_pg_mapping(pg, &map->pg_temp);
+		if (err)
+			goto bad;
 		dout(" added pg_temp %llx len %d\n", pgid, len);
 	}
 
@@ -681,7 +684,9 @@
 			pg->len = pglen;
 			for (j = 0; j < len; j++)
 				ceph_decode_32(p, pg->osds[j]);
-			__insert_pg_mapping(pg, &map->pg_temp);
+			err = __insert_pg_mapping(pg, &map->pg_temp);
+			if (err)
+				goto bad;
 			dout(" added pg_temp %llx len %d\n", pgid, pglen);
 		}
 	}