This is insane.
After waiting an hour or so after my initial --sync, I again ran --sync, and this time it seems portage successfully deleted all the old files.
I compared the sync logs, and even though there is no obvious file troubles that would suggest a cause for the reported IO error, e.g. permissions, bad symlinks, etc., I see a subtle difference comparing the failed vs. successful --sync logs. It seems as if during the failed run, there are multiple concurrent 'flists' operations occurring for directories, almost as if rsync was performing these ops asynchronously. However, in the successful run, the 'flist' operations seem to be serialized. My wild ass guess is that perhaps during the failed run, there is some resource contention/locking that is happening for the concurrent flists, and this leads to a blocked attempt at deleting one of the directories. I have researched the parameters for rsync, and there appears to be no functionality controlling concurrent operation. For my purposes, I am not passing any special parameters to rsync, only increase verbosity to record more debug info.
Here is an excerpt from the failed --sync, just before the initial delete_in_dir(app-accessibility). Notice the interweaving "receiving filst" entries:
[receiver] receiving flist for dir 229
[generator] i=191 2 app-accessibility/festival-it/ mode=040755 len=88 flags=4
[generator] i=192 2 app-accessibility/festival-ru/ mode=040755 len=85 flags=4
[generator] i=193 2 app-accessibility/festival/ mode=040755 len=123 flags=4
[generator] i=194 2 app-accessibility/flite/ mode=040755 len=4096 flags=4
[receiver] receiving flist for dir 197
[generator] i=195 2 app-accessibility/freetts/ mode=040755 len=155 flags=4
[generator] i=196 2 app-accessibility/gnome-mag/ mode=040755 len=86 flags=4
[generator] i=197 2 app-accessibility/gnome-speech/ mode=040755 len=104 flags=4
[generator] i=198 2 app-accessibility/gok/ mode=040755 len=80 flags=4
[generator] i=199 2 app-accessibility/java-access-bridge/ mode=040755 len=146 flags=4
[receiver] receiving flist for dir 198
[generator] i=200 2 app-accessibility/julius/ mode=040755 len=94 flags=4
[generator] i=201 2 app-accessibility/mbrola/ mode=040755 len=116 flags=4
[generator] i=202 2 app-accessibility/morseall/ mode=040755 len=84 flags=4
[generator] i=203 2 app-accessibility/nfbtrans/ mode=040755 len=125 flags=4
[generator] i=204 2 app-accessibility/orca/ mode=040755 len=130 flags=4
[receiver] receiving flist for dir 199
[generator] i=205 2 app-accessibility/perlbox-voice/ mode=040755 len=126 flags=4
[generator] i=206 2 app-accessibility/pidgin-festival/ mode=040755 len=89 flags=4
[generator] i=207 2 app-accessibility/pocketsphinx/ mode=040755 len=86 flags=4
[generator] i=208 2 app-accessibility/powiedz/ mode=040755 len=96 flags=4
[receiver] receiving flist for dir 200
[generator] i=209 2 app-accessibility/simon/ mode=040755 len=118 flags=4
[generator] i=210 2 app-accessibility/sound-icons/ mode=040755 len=85 flags=4
[generator] i=211 2 app-accessibility/speakup/ mode=040755 len=150 flags=4
[generator] i=212 2 app-accessibility/speech-dispatcher/ mode=040755 len=4096 flags=4
[receiver] receiving flist for dir 201
[generator] i=213 2 app-accessibility/speech-tools/ mode=040755 len=4096 flags=4
[generator] i=214 2 app-accessibility/speechd-el/ mode=040755 len=84 flags=4
[generator] i=215 2 app-accessibility/speechd-up/ mode=040755 len=99 flags=4
[generator] i=216 2 app-accessibility/sphinx2/ mode=040755 len=93 flags=4
[generator] i=217 2 app-accessibility/sphinx3/ mode=040755 len=120 flags=4
[receiver] receiving flist for dir 230
[generator] i=218 2 app-accessibility/sphinxbase/ mode=040755 len=124 flags=4
[generator] i=219 2 app-accessibility/yasr/ mode=040755 len=95 flags=4
recv_file_list done
[receiver] receiving flist for dir 202
[receiver] receiving flist for dir 231
recv_generator(app-accessibility,172)
delete_in_dir(app-accessibility)
IO error encountered -- skipping file deletion
recv_generator(app-accessibility/metadata.xml,173)
Now here is an excerpt from the successful --sync. Notice the missing flists this time:
[generator] flist start=173, used=47, low=0, high=46
[generator] i=173 2 app-accessibility/metadata.xml mode=0100644 len=1652 flags=0
[generator] i=174 2 app-accessibility/SphinxTrain/ mode=040755 len=133 flags=4
[generator] i=175 2 app-accessibility/accerciser/ mode=040755 len=117 flags=4
[generator] i=176 2 app-accessibility/at-spi2-atk/ mode=040755 len=4096 flags=4
[generator] i=177 2 app-accessibility/at-spi2-core/ mode=040755 len=4096 flags=4
[generator] i=178 2 app-accessibility/brltty/ mode=040755 len=122 flags=4
[generator] i=179 2 app-accessibility/caribou/ mode=040755 len=84 flags=4
[generator] i=180 2 app-accessibility/dasher/ mode=040755 len=81 flags=4
[generator] i=181 2 app-accessibility/edbrowse/ mode=040755 len=152 flags=4
[generator] i=182 2 app-accessibility/eflite/ mode=040755 len=94 flags=4
[generator] i=183 2 app-accessibility/emacspeak-ss/ mode=040755 len=100 flags=4
[generator] i=184 2 app-accessibility/emacspeak/ mode=040755 len=146 flags=4
[generator] i=185 2 app-accessibility/epos/ mode=040755 len=96 flags=4
[generator] i=186 2 app-accessibility/espeak/ mode=040755 len=87 flags=4
[generator] i=187 2 app-accessibility/espeakup/ mode=040755 len=122 flags=4
[generator] i=188 2 app-accessibility/festival-fi/ mode=040755 len=102 flags=4
[generator] i=189 2 app-accessibility/festival-freebsoft-utils/ mode=040755 len=141 flags=4
[generator] i=190 2 app-accessibility/festival-hts/ mode=040755 len=86 flags=4
[generator] i=191 2 app-accessibility/festival-it/ mode=040755 len=88 flags=4
[generator] i=192 2 app-accessibility/festival-ru/ mode=040755 len=85 flags=4
[generator] i=193 2 app-accessibility/festival/ mode=040755 len=123 flags=4
[generator] i=194 2 app-accessibility/flite/ mode=040755 len=4096 flags=4
[generator] i=195 2 app-accessibility/freetts/ mode=040755 len=155 flags=4
[generator] i=196 2 app-accessibility/gnome-mag/ mode=040755 len=86 flags=4
[generator] i=197 2 app-accessibility/gnome-speech/ mode=040755 len=104 flags=4
[generator] i=198 2 app-accessibility/gok/ mode=040755 len=80 flags=4
[generator] i=199 2 app-accessibility/java-access-bridge/ mode=040755 len=146 flags=4
[generator] i=200 2 app-accessibility/julius/ mode=040755 len=94 flags=4
[generator] i=201 2 app-accessibility/mbrola/ mode=040755 len=116 flags=4
[generator] i=202 2 app-accessibility/morseall/ mode=040755 len=84 flags=4
[generator] i=203 2 app-accessibility/nfbtrans/ mode=040755 len=125 flags=4
[generator] i=204 2 app-accessibility/orca/ mode=040755 len=130 flags=4
[generator] i=205 2 app-accessibility/perlbox-voice/ mode=040755 len=126 flags=4
[generator] i=206 2 app-accessibility/pidgin-festival/ mode=040755 len=89 flags=4
[generator] i=207 2 app-accessibility/pocketsphinx/ mode=040755 len=86 flags=4
[generator] i=208 2 app-accessibility/powiedz/ mode=040755 len=96 flags=4
[generator] i=209 2 app-accessibility/simon/ mode=040755 len=118 flags=4
[generator] i=210 2 app-accessibility/sound-icons/ mode=040755 len=85 flags=4
[generator] i=211 2 app-accessibility/speakup/ mode=040755 len=150 flags=4
[generator] i=212 2 app-accessibility/speech-dispatcher/ mode=040755 len=4096 flags=4
[generator] i=213 2 app-accessibility/speech-tools/ mode=040755 len=4096 flags=4
[generator] i=214 2 app-accessibility/speechd-el/ mode=040755 len=84 flags=4
[generator] i=215 2 app-accessibility/speechd-up/ mode=040755 len=99 flags=4
[generator] i=216 2 app-accessibility/sphinx2/ mode=040755 len=93 flags=4
[generator] i=217 2 app-accessibility/sphinx3/ mode=040755 len=120 flags=4
[generator] i=218 2 app-accessibility/sphinxbase/ mode=040755 len=124 flags=4
[generator] i=219 2 app-accessibility/yasr/ mode=040755 len=95 flags=4
recv_file_list done
recv_generator(app-accessibility,172)
delete_in_dir(app-accessibility)
[generator] make_file(app-accessibility/julius,*,2)
[generator] make_file(app-accessibility/speech-tools,*,2)