Just an array of bits, one per block. For a 300 Mbyte drive there are about 300000 1kbyte blocks, so bit map takes up 40000 bytes. Keep only a small part of the bit map in memory at once. In allocation, scan bit map for adjacent free blocks. It's easy to allocate block groups, since the bit map automatically merges adjacent free blocks.
File descriptors take up less space on disk, require fewer accesses in random access to large files.
When disk becomes full, this becomes VERY expensive, and doesn't get much in the way of adjacency.