Reducing boilerplate of binary layout handling in Haskell
To add one more suggestion - building records can be simplified quite a bit by using the RecordWildCards extension, which automatically populates fields from visible names (see GHC docs). Personally, I consider it borderline essential for dealing with large records. I would probably write this like follows:

{-# LANGUAGE RecordWildCards #-}
-- ...
binGetSuperblock = do
  [sInodesCount,         sBlocksCount,
   sReservedBlocksCount, sFreeBlocksCount,
   sFreeInodesCount,     sFirstDataBlock,
   sLogBlockSize,        sLogClusterSize,
   sBlocksPerGroup,      sClustersPerGroup,
   sInodesPerGroup,      sMountTime,
   sWriteTime]                            &lt;- replicateM 13 getWord32le
  [sMountsCount,         sMaxMountsCount,
   sMagic,               sState,
   sErrors,              sRevLevel2]      &lt;- replicateM 6  getWord16le
  [sLastCheckTime,       sCheckInterval,
   sCreatorOS,           sRevLevel1]      &lt;- replicateM 4  getWord32le
  [sDefaultResUID,       sDefaultResGID]  &lt;- replicateM 2  getWord16le
  return Superblock {
    sMaxMountsCount = int sMaxMountsCount,
    sRevLevel = (sRevLevel1, sRevLevel2),
    sDynRev = Nothing,
    sPrealloc = Nothing,
    sJournaling = Nothing,
    ..
    }