MKUDFFS(8)

πŸ“¦
version 2.3 Β· 2 versions
  • 2.3 Β· alpine 3.24, arch rolling, debian bookworm, debian trixie, fedora 43, fedora 44, nixos 26.05, nixpkgs unstable, opensuse-leap 16.0, ubuntu jammy, ubuntu noble, ubuntu questing, ubuntu resolute, ubuntu stonking (latest)
  • 2.2 Β· centos-stream 9
, in alpine 3.24, arch rolling, debian bookworm, debian trixie, fedora 43, fedora 44, nixos 26.05, nixpkgs unstable, opensuse-leap 16.0, ubuntu jammy, ubuntu noble, ubuntu questing, ubuntu resolute, ubuntu stonking

🌸 MKUDFFS(8) β€” the System Manager's Manual page, but make it make sense πŸ’–

okay bestie, sit down, grab a snack πŸ“, because today we're manifesting a UDF filesystem and honestly? it's giving main character energy.


✨ NAME ✨

mkudffs β€” create a UDF filesystem πŸ¦‹


✨ SYNOPSIS ✨

mkudffs [ options ] device [ blocks-count ]

✨ DESCRIPTION ✨

so like, mkudffs is the girl who builds a UDF filesystem on a device (usually a disk, obviously πŸ’…).

  • device β€” the special file that corresponds to the device (e.g. /dev/hdX) or a file image. yes, a plain file counts, she's flexible like that.
  • blocks-count β€” the number of blocks on the device. if you don't give her one, mkudffs automagically figures out the filesystem size herself. queen behavior, no cap. πŸ‘‘
⚠️ THE ORDER OF OPTIONS MATTERS. the encoding option must be first, and any option that overrides default settings implied by the media type or UDF revision has to come after the option it's overriding. don't shuffle, bestie, she will not forgive you 😭

✨ OPTIONS ✨

  • -h, --help β€” display the usage and list of options. the classic "help me help you" move 🫢
  • -l, --label= label β€” specify the UDF label. a UDF label is basically a synonym for setting both --lvid and --vid at once. if you omit it, the mkudffs label is LinuxUDF. (option available since mkudffs 1.1) πŸŽ€
  • -u, --uuid= uuid β€” specify the UDF uuid. it must be exactly 16 hexadecimal lowercase digits and it's used for the first 16 characters of the --fullvsid option. if omitted, the mkudffs uuid is generated from local time plus a random number. (option available since mkudffs 1.1) ✨
  • -b, --blocksize= block-size β€” specify the size of blocks in bytes. a valid block size for a UDF filesystem is a power of two in range from 512 to 32768, and it must match the device logical (sector) size. if omitted, the mkudffs block size is set to the device logical block (sector) size. if the logical block (sector) size is unknown (e.g. when creating a disk image) then for --media-type=hd it uses block size 512 and for other media types 2048. (prior to mkudffs 1.1 the default value was always 2048 independently of --media-type) πŸ’€
  • -m, --media-type= media-type β€” specify the media type. it must be specified before --udfrev. default value is autodetected. when autodetection does not work (e.g. when creating a disk image) then the hd value is assumed. valid media types are:
    • hd β€” HD (Hard Disk)
    • worm β€” WORM (Write Once Read Many)
    • mo β€” MO (Magneto Optical)
    • cd β€” CD-ROM (CD Read-Only Memory)
    • cdr β€” CD-R (CD Recordable)
    • cdrw β€” CD-RW (CD Read-Write)
    • dvd β€” DVD-ROM (DVD Read-Only Memory)
    • dvdr β€” DVD-R (DVD Recordable)
    • dvdrw β€” DVD-RW (DVD Read-Write)
    • dvdram β€” DVD-RAM (DVD Random Access Memory)
    • bdr β€” BD-R (Blu-ray Disc Recordable)

(short option variant -m and values cd, dvdr, bdr are available since mkudffs 2.0, and autodetection is supported since mkudffs 2.2) 🌈

  • -r, --udfrev= udf-revision β€” specify the UDF revision to use, either in hexadecimal BCD (e.g. 0x0201) or decimal (e.g. 2.01) format. valid revisions are 1.01, 1.02, 1.50, 2.00, 2.01, 2.50 and 2.60. if omitted, the mkudffs UDF revision is 2.01, except for Blu-ray Discs which is 2.50. UDF revisions higher than 2.01 are experimental ⚠️. option must be specified after --media-type. (values in decimal format and UDF revisions higher than 2.01 are supported since mkudffs 2.0, UDF revision 1.01 is supported since mkudffs 2.1)
  • -n, --no-write β€” not really, do not write to device. just simulate and display what would happen with the device. super useful for determining the calculated location of different UDF blocks. (option available since mkudffs 2.0) πŸ™ˆ
  • --new-file β€” create a new image file specified by device with blocks-count and fail if the file already exists. if omitted, mkudffs creates a new image file only in case it does not exist yet. (option available since mkudffs 2.0)
  • --lvid= logical-volume-identifier β€” specify the Logical Volume Identifier. if omitted, the mkudffs Logical Volume Identifier is LinuxUDF. most UDF implementations use this identifier as a disk label. 🏷️
  • --vid= volume-identifier β€” specify the Volume Identifier. if omitted, the mkudffs Volume Identifier is LinuxUDF.
  • --vsid= volume-set-identifier β€” specify the 17.–127. character of Volume Set Identifier. if omitted, the mkudffs Volume Set Identifier is LinuxUDF.
  • --fsid= file-set-identifier β€” specify the File Set Identifier. if omitted, the mkudffs File Set Identifier is LinuxUDF.
  • --fullvsid= full-volume-set-identifier β€” specify the full Volume Set Identifier. overwrites previous --uuid and --vsid options. (option available since mkudffs 1.1) πŸ’₯
  • --owner= owner-name β€” specify the Owner name, aka the person creating the medium or filesystem. it's stored in UDF Logical Volume Info1, part of UDF Implementation Use Volume Descriptor. (option available since mkudffs 2.3) πŸ‘‘
  • --organization= organization-name β€” specify the Organization name responsible for creating the medium or filesystem. it's stored in UDF Logical Volume Info2, part of UDF Implementation Use Volume Descriptor. (option available since mkudffs 2.3)
  • --contact= contact-information β€” specify the Contact information for the medium or filesystem. it's stored in UDF Logical Volume Info3, part of UDF Implementation Use Volume Descriptor. (option available since mkudffs 2.3) πŸ’Œ
  • --uid= uid β€” specify the uid of the root (/) directory. if omitted, the mkudffs uid is 0. special value -1 means invalid or not specified uid. (option available since mkudffs 1.1)
  • --gid= gid β€” specify the gid of the root (/) directory. if omitted, the mkudffs gid is 0. special value -1 means invalid or not specified gid. (option available since mkudffs 1.1)
  • --mode= mode β€” specify permissions in octal mode bits of the root (/) directory. if omitted, the mkudffs mode is 0755. (option available since mkudffs 2.0) πŸ”
  • --read-only β€” this option specifies that the whole UDF disk should be treated as read-only. it sets the SoftWriteProtect domain flag in the Logical Volume Descriptor and in the File Set Descriptor. plus, for overwritable media types (hd, dvdram, dvdrw) it sets the UDF Access Type to read-only. (option available since mkudffs 2.2) βœ‹
  • --bootarea= fill β€” specify how to fill the UDF boot area, which is the first 32kB of the disk and is not used by UDF itself. the mbr option only makes sense when running mkudffs on a whole disk, not on just one partition. valid options are:
    • preserve β€” preserve existing UDF boot area, do not touch it (default for media type different from hd)
    • erase β€” erase existing UDF boot area, fill it by zeros (default for hd media type on partitions and on removable disks)
    • mbr β€” put an MBR table with one partition which starts at sector 0 (includes the MBR itself) and spans the whole disk device, needed only for non-removable hard disks used on Microsoft Windows systems (default for hd media type on non-removable hard disk without partitions), see the section WHOLE DISK VS PARTITION
    • mbr:sec-size β€” same as mbr but explicitly set MBR sector size to sec-size value, default sec-size is device logical block (sector) size with fallback to size 512 bytes

(option available since mkudffs 2.0) 🌸

  • --strategy= strategy β€” specify the allocation strategy to use. valid strategies are 4 and 4096. if omitted, the mkudffs strategy is based on the --media-type.
  • --spartable, --spartable= spartable-number β€” enable usage of Sparing Table. optionally specify also the number of sparing tables. valid numbers are 1–4. when the spartable number is omitted then two tables are written to the disc. if the option is omitted then usage of Sparing Table depends on the media type. (prior to mkudffs 2.0 this option was available only for cdrw media type)
  • --sparspace= num-of-entires β€” specify the number of entries in the Sparing Table. if omitted, the default number of entries is 1024, but it depends on the media type. (option available since mkudffs 2.0) ✨
  • --packetlen= length β€” packet length in a number of blocks used for alignment. all continuous UDF structures would be aligned to packets. it also specifies the size of the Sparing Space and packet length in the Sparing Table. it should match the device ECC/packet length. if omitted, the default value for DVD discs is 16 blocks, for CD/BD discs it is 32 blocks and otherwise 1 block. (prior to mkudffs 2.1 this option was available only for cdrw and dvdrw media types) πŸ“¦
  • --vat β€” enable usage of Virtual Allocation Table (VAT). if omitted, usage depends on the media type. (option available since mkudffs 2.0)
  • --startblock= start-block β€” specify the block location where the UDF filesystem starts.

normally the start block is 0, but when creating a second or higher session for a Multisession UDF optical disc it is the block location where that new session starts.

when updating an existing Multisession UDF image file, mkudffs overwrites only data blocks for a new session at the start-block position in the image file.

when creating a new UDF image file, mkudffs stores only data blocks for a new session at the beginning of the image file. therefore data for start-block would be written to the zero block instead of the start block. such an image without leading blocks (where previous sessions are located) is suitable for burning a new session to the optical disc. but it cannot be read or detected by any UDF tool until leading zero blocks (or previous sessions) are prepended to the image file. πŸ’€

for calculating the position where a new session of a particular optical disc should start, you're required to use the software that would be used for burning the newly created image. so for example, if for burning you use wodim(1) then the second value on the output from wodim -msinfo is the start block. accordingly, for cdrecord(1) call cdrecord -msinfo, or for cdrdao(1) call cdrdao msinfo, or for xorriso(1) call xorriso -as cdrecord dev=/dev/cdrw -msinfo.

(option available since mkudffs 2.3) πŸ”₯


okay so that's the first chunk bestie, and there's more coming β€” don't go anywhere πŸ’–

  • --minblocks= min-num-of-blocks β€” bestie, this sets the minimal number of blocks that get written on the disc alongside the Virtual Allocation Table. πŸŽ€

It changes the block position where the Virtual Allocation Table lands. And if you're also using --closed, then yeah, it also moves where the second Anchor Volume Descriptor Pointer goes. Two for one.

The default value for cdr media type is 300. That's a nice safe default so you can burn a CD-R disc image in Track-at-Once mode β€” that mode needs an image of at least 300 sectors. If you burn CD-Rs in other modes (like Disc-at-Once or Packet-Writing) you might be able to get away with smaller disc images. πŸ‘€

For every other media type, there's no default minimal limit. Periodt.

(Option available since mkudffs 2.3)
  • --closed β€” closes the disc with the Virtual Allocation Table, and the AVDP also gets written to the end of the disc. By default? The disc with a Virtual Allocation Table is not closed. So if you want it sealed, say it. πŸ’…
  • --space= space β€” picks the Space Set. ✨ Here's the tea: the Unallocated Space Set is for media whose blocks can be allocated immediately. The Freed Space Set is for media whose blocks need to be specially prepared/erased before they can be allocated. In the Space Table there's a list of unallocated extents. In the Space Bitmap there's a bitmap of unallocated blocks. Not used for VAT.
    • freedbitmap β€” Freed Bitmap
    • freedtable β€” Freed Table
    • unallocbitmap β€” Unallocated Bitmap (default)
    • unalloctable β€” Unallocated Table
  • --ad= ad β€” sets the Allocation Descriptors of the root (/) directory. πŸ‘‘
    • inicb β€” Allocation Descriptors in ICB (default)
    • short β€” Short Allocation Descriptors
    • long β€” Long Allocation Descriptors
  • --noefe β€” do not use Extended File Entries for the root (/) directory. Only affects UDF 2.00 or higher. And bestie, listen: it must be specified after --udfrev. Order matters, no cap. ⚠️
  • --locale β€” treats identifier string options as strings encoded according to the current locale settings (this is the default). Must be specified as the first argument. 🌸 (Option available since mkudffs 2.0)
  • --u8 β€” treats identifier string options as strings encoded in 8-bit OSTA Compressed Unicode format without the leading Compression ID byte, which is equivalent to Latin1 (ISO-8859-1). Must be specified as the first argument.
  • --u16 β€” treats identifier string options as strings encoded in 16-bit OSTA Compressed Unicode format without the leading Compression ID byte, which is equivalent to UTF-16BE. Heads up though: you literally cannot include a zero byte in command line options, so any character with at least one zero byte can't be supplied at all (and yes, that applies to all Latin1 characters 😭). Must be specified as the first argument.
  • --utf8 β€” treats identifier string options as strings encoded in UTF-8. Must be specified as the first argument. πŸ¦‹ (Prior to mkudffs 2.0 this was the default option)

🌈 COMPATIBILITY 🌈

πŸ’» OPERATING SYSTEMS SUPPORT

UDF filesystem is natively supported by a huge amount of operating systems, and honestly? iconic. Here's the compatibility table, but rendered as a list because we're in a terminal, bestie. The columns are: operating system Name, its Version, the maximum UDF revision for read, and the maximum UDF revision for write.

  • Linux 🐧
    • 2.3.17 – 2.4.5 β€” read 2.00, write 2.00
    • 2.4.6 – 2.6.25 β€” read 2.01, write 2.01
    • 2.6.26 (and new) β€” read 2.50, write 2.01
  • Windows πŸͺŸ
    • 98/Me β€” read 1.02, write none
    • 2000 β€” read 1.50, write none
    • XP β€” read 2.01, write none
    • Vista (and new) β€” read 2.60, write 2.50
  • Mac OS 🍎
    • 8.1 – 8.5 β€” read 1.02, write none
    • 8.6 – 9.2 β€” read 1.50, write 1.50
  • Mac OS X
    • 10.0 – 10.3 β€” read 1.50, write 1.50
    • 10.4 β€” read 2.01, write 2.01
    • 10.5 (and new) β€” read 2.60, write 2.50
  • FreeBSD 😈
    • 5 (and new) β€” read 1.50, write none
  • NetBSD
    • 4.0 β€” read 2.60, write none
    • 5.0 (and new) β€” read 2.60, write 2.60
  • OpenBSD 🐑
    • 3.8 – 3.9 β€” read 1.02, write (blank in the table, nothing listed)
    • 4.0 – 4.6 β€” read 1.50, write none
    • 4.7 (and new) β€” read 2.60, write (blank in the table, nothing listed)
  • Solaris β˜€οΈ
    • 7 (and new) β€” read 1.50, write 1.50
  • AIX
    • 5.2 (and new) β€” read 2.01, write 2.01
Note that Windows 98 and Windows Me can read UDF filesystem only from CD and DVD optical discs β€” not from hard disks. 🫠

πŸ“ BLOCK SIZE

In most cases, operating systems are unable to mount a UDF filesystem if the UDF block size differs from the logical sector size of the device. That's just how it is, bestie. Typically hard disks have a sector size of 512 bytes and optical media have 2048 bytes. So the rule is simple: UDF block size must match the logical sector size of the device. πŸ’…

Now the Linux kernel lore, because it's a journey:

  • Linux kernel prior to version 2.6.30 used a hardcoded UDF block size of 2048 bytes, independent of logical sector size. So it couldn't automatically mount a UDF filesystem if the block size differed from 2048. πŸ™ˆ
  • Since 2.6.30 and prior to 4.11, the Linux kernel used the logical sector size of the device as the UDF block size, plus it tried a fallback to 2048.
  • Since 4.11, it uses the logical sector size and fallbacks to any valid block size between the logical sector size and 4096.

So basically: since version 2.6.30 the Linux kernel can automatically mount UDF filesystems correctly if the UDF block size matches the device logical sector size, and since version 4.11 it can automatically also mount devices whose sector size does not match the UDF block size. Slay. ✨

But in any case β€” and also for Linux kernel prior to version 2.6.30 β€” a different UDF block size (one that isn't autodetected) can be manually specified via the bs=blocksize mount parameter. πŸŽ€

πŸ’½ WHOLE DISK VS PARTITION

UDF filesystem is supposed to be formatted on the whole media, not on a partitioned hard disk. That's the design, okay?

  • Mac OS X systems enforce this rule and will reject automatically mounting a UDF filesystem unless it's formatted on the whole unpartitioned hard disk. Any possible partition table (like MBR or GPT) on a disk with a valid UDF filesystem is ignored. 😀
  • Microsoft Windows systems, on the other hand, are unable to detect non-removable hard disks without an MBR or GPT partition table. Removable disks don't have this restriction.

The consequence is messy: non-removable hard disks formatted to UDF by Windows Vista+ are not recognized by Mac OS X systems, and vice versa. πŸ’€

Note that manual mount of a UDF partition on a partitioned hard disk on a Mac OS X system is possible and working β€” e.g. by running these commands: mkdir /Volumes/DriveName && mount_udf /dev/disk1s1 /Volumes/DriveName But there is no known way to mount an unpartitioned non-removable disk on a Windows system. 😭

Okay but here's the clever part. Thanks to the reserved and unused UDF boot area (the first 32kB of the UDF filesystem) it's possible to deal with this whole problem by putting an MBR on such a non-removable hard disk just for compatibility reasons with Windows. That MBR table would contain one partition which starts at sector 0 (so it includes the MBR itself) and spans the whole disk device. So the whole disk device and also the first partition on the disk point to the same sectors. 🧠✨

Therefore the UDF filesystem can be mounted either from the whole disk device (needed for Mac OS X systems) or from the first partition (needed for Microsoft Windows systems). Both. Gorgeous.

  • The Linux kernel ignores an MBR table if it contains a partition which starts at sector 0. Normally the Linux kernel can detect and mount UDF filesystem either on a partition or on a whole disk device. It does not have any restrictions. πŸ‘‘

And guess what β€” the mkudffs option --bootarea=mbr puts exactly such an MBR table for compatibility with Microsoft Windows systems into the disk when formatting. 🫢

🏷️ LINUX LABEL BUGS

In most cases the Logical Volume Identifier is used as the UDF label. But:

  • Linux libblkid prior to version 2.26 used the Volume Identifier. So mkudffs --label, for compatibility reasons, sets both the Logical Volume Identifier and the Volume Identifier.
  • Linux libblkid prior to version 2.30 incorrectly processed non-ASCII identifier strings encoded in 8-bit OSTA Compressed Unicode format. So mkudffs, since version 2.0, for compatibility reasons tries to encode non-ASCII identifier strings in 16-bit OSTA Compressed Unicode format and then fallbacks to 8-bit format.

For more information about UDF Label and UUID, go check udflabel(8) section UDF LABEL AND UUID. πŸ“–


🚦 EXIT STATUS

mkudffs returns 0 if successful, non-zero if there are problems. Simple as that, bestie. πŸ’–

😭 LIMITATIONS (aka the fine print bestie, read it)

Okay so real talk, mkudffs is not perfect and we're gonna be honest about it.

  • mkudffs cannot create a UDF 2.50 Metadata partition, which means it does not support UDF revisions higher than 2.01 for non Write Once media. Not yet, anyway. 🫠
  • So there is no support for Blu-ray discs, because those need UDF 2.50. The one exception? Blu-ray Disc Recordable, which does not require a Metadata partition, so that one's fine. πŸ’…

Also, ancient lore: mkudffs prior to version 2.2 could not process Unicode strings with code points above U+FFFF. Like, at all.

  • When option --utf8 was specified, input strings were limited to 3-byte UTF-8 sequences.
  • When option --u16 was specified, input strings were limited just to UCS-2BE strings (which is a subset of UTF-16BE).

So if you're on something old, that's your vibe check. πŸ¦‹


πŸ’€ BUGS (the cringe historical era)

Not me exposing the ancestors, but fr fr:

  • mkudffs prior to version 1.1 was unable to process non-ASCII characters from identifier strings in --utf8 mode, --vsid was completely broken, and --blocksize had to be manually specified for hard disks because the default value was hardcoded for optical disks. πŸ™ˆ
  • mkudffs prior to version 2.0 generated broken and unreadable cdr disc images.
If you are on one of these old versions: please upgrade, bestie, I am begging you. 😭

πŸ‘‘ AUTHOR

  • Ben Fennema
  • Pali RohΓ‘r <pali.rohar@gmail.com>

Icons. Legends. Main characters, honestly. πŸŽ€


🌈 AVAILABILITY

mkudffs is part of the udftools package and is available from https://github.com/pali/udftools/. Go get it, it's free, it's iconic. ⭐


🫢 SEE ALSO


And that's the whole page, bestie!! πŸŽ€ This lil masterpiece lives in the udftools package and hangs out in the System Management Commands section of the manual, as MKUDFFS(8). Now go make some filesystems, you absolute genius. Periodt. πŸ’–βœ¨πŸ¦‹