The calculated status field could also be indexed by setting it via a script when the data it relies on changes. I tend to set any fields like that using a script so that there aren't any critical un-indexed fields. That keeps the speed.
I'm not sure if it qualifies as a third option, but I have in the past set up both a calculated field and a regular field with an auto-entered calculation or lookup that fires every time the record is modified.
Also, to mitigate your slow finds with your option two you can create your find requests differently - FileMaker isn't clever enough to do a multiple pass search every time on its own (yet), so do it manually by only searching on indexed fields first, then constraining the found set with your criteria for the unstored field(s). That way you're minimising the chance of needing to poll every record for a value. It usually helps to make a scripted find process for these situations.
And for option one, it helps to treat a status update for the parent record as a transactional activity. You can find a bit more information here, but the gist of it is that you want the process to either complete 100% successfully or fail. You first try to obtain a lock on the parent record; if that succeeds you go through each portal row for the child records and try to update each one. On any failure, revert the parent record and all related records will also be reverted. Otherwise, commit the parent record and all related records will also be committed.