How do pdflush, kjournald, swapd, etc interoperate?

Recently saw a question that sparked this thought. Couldn’t really find an answer here or via the Google machine. Basically, I’m interested in knowing how the kernel I/O architecture is layered. For example, does kjournald dispatch to pdflush or the other way around? My assumption is that pdflush (being more generic to mass storage I/O) would sit at a lower level and trigger the SCSI/ATA/whatever commands necessary to actually perform the writes, and kjournald handles higher level filesystem data structures before writing. I could see it the other way around as well, though, with kjournald directly interfacing with the filesystem data structures and pdflush waking up every now and then to write dirty pagecache pages to the device through kjournald. It’s also possible that the two don’t interact at all for some other reason.