Hmm... there's a couple of ways to do that too
Option 1: A Timer
ssh -2 -f -x -L 2401:localhost:email@example.com sleep 10; cvs -d :pserver:jza@localhost:/cvs login
(Note that we leave off the '-N' option) The timer will keep the tunnel open for 10 seconds by itself, but the tunnel shouldn't close until after your cvs command finishes. After the cvs command finishes, the tunnel should close automagically. I haven't tested this one yet, but it's based on one of the examples in that link I posted before. Looks like the cleanest option!
Option 2: Capture the pid, kill when finished
# start the tunnel, use bash to send it to the background instead of "-f"
ssh -2 -N -x -L 2401:localhost:firstname.lastname@example.org &
# $! gives us the pid of he last process sent to the background
# run your cvs command
cvs -d :pserver:jza@localhost:/cvs login
# Kill the tunnel
kill -9 $PID
The problem with option 2 is it tends to leave the tunnel port occupied until it times out, so it's kind of a dirty way to do it. I think Option 1 is the best way to go, and I learned several new things trying to figure it out!
Hope it helps!