diff --git a/include/linux/crush/crush.h b/include/linux/crush/crush.h
index 83543c504b5a..3d6a12928560 100644
--- a/include/linux/crush/crush.h
+++ b/include/linux/crush/crush.h
@@ -19,10 +19,11 @@
 
 #define CRUSH_MAGIC 0x00010000ul   /* for detecting algorithm revisions */
 
-
 #define CRUSH_MAX_DEPTH 10  /* max crush hierarchy depth */
 
 
+#define CRUSH_ITEM_UNDEF  0x7fffffff  /* undefined result */
+
 /*
  * CRUSH uses user-defined "rules" to describe how inputs should be
  * mapped to devices.  A rule consists of sequence of steps to perform
diff --git a/net/ceph/crush/mapper.c b/net/ceph/crush/mapper.c
index dcf48bc504ea..a8605245d190 100644
--- a/net/ceph/crush/mapper.c
+++ b/net/ceph/crush/mapper.c
@@ -455,8 +455,12 @@ static int crush_choose(const struct crush_map *map,
 		} while (retry_descent);
 
 		if (skip_rep) {
-			dprintk("skip rep\n");
-			continue;
+			if (firstn) {
+				dprintk("skip rep\n");
+				continue;
+			}
+			dprintk("undef rep, continuing\n");
+			item = CRUSH_ITEM_UNDEF;
 		}
 
 		dprintk("CHOOSE got %d\n", item);