Давайте не будем рефакторить этот код а создадим новую функцию. Которая делает тоже самое и докажем что полученый код эквивалентен. Тогда и проблема goto будет иметь еще одно решение. Наша функция предположительно будет такая:
int find_first_zero_row(int **matrix, int cols, int rows) {
.....
return -1;
}
Будет такой контракт что если строка из нулей найдена то мы получаем ее номер или -1 в противном случае.
Нам может понадобиться вспомогательная функция.
int all_items_are_zero(int *items, int length) {
....
}
Мне кажется что с таким набором нам не понадобится goto. Декомпозиция кода на функции - это один из способов избежать goto.
P.S. Не бойтесь вводить в код функции. Торвальдс не запрещает функции в языке С. Ценнее код который работает правильно а не тот который выглядит как колбаса и глючит временами.