options: ensure that we check all candidates on is_set check

We can have multiple options that touch the same variable. One
example is cpus_allowed or cpumask, both will set the same
backend variable. But if we set cpumask= and later check if
cpus_allowed is set, then we want that to report true.

This breaks certain options since b2a9e6496494.

Reported-by: Vincent Fu <Vincent.Fu@sandisk.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
diff --git a/options.c b/options.c
index e3c9c87..3e783c1 100644
--- a/options.c
+++ b/options.c
@@ -4191,21 +4191,32 @@
 	return find_option(fio_options, name);
 }
 
-int __fio_option_is_set(struct thread_options *o, unsigned int off1)
+static struct fio_option *find_next_opt(struct thread_options *o,
+					struct fio_option *from,
+					unsigned int off1)
 {
-	unsigned int opt_off, index, offset;
-	struct fio_option *opt = NULL;
-	int i;
+	struct fio_option *opt;
 
-	for (i = 0; fio_options[i].name; i++) {
-		if (off1 == fio_options[i].off1) {
-			opt = &fio_options[i];
+	if (!from)
+		from = &fio_options[0];
+	else
+		from++;
+
+	opt = NULL;
+	do {
+		if (off1 == from->off1) {
+			opt = from;
 			break;
 		}
-	}
+		from++;
+	} while (from->name);
 
-	if (!opt)
-		return -1;
+	return opt;
+}
+
+static int opt_is_set(struct thread_options *o, struct fio_option *opt)
+{
+	unsigned int opt_off, index, offset;
 
 	opt_off = opt - &fio_options[0];
 	index = opt_off / (8 * sizeof(uint64_t));
@@ -4213,6 +4224,21 @@
 	return (o->set_options[index] & (1UL << offset)) != 0;
 }
 
+int __fio_option_is_set(struct thread_options *o, unsigned int off1)
+{
+	struct fio_option *opt, *next;
+
+	next = NULL;
+	while ((opt = find_next_opt(o, next, off1)) != NULL) {
+		if (opt_is_set(o, opt))
+			return 1;
+
+		next = opt;
+	}
+
+	return 0;
+}
+
 void fio_option_mark_set(struct thread_options *o, struct fio_option *opt)
 {
 	unsigned int opt_off, index, offset;