David Brazdil | 0f672f6 | 2019-12-10 10:32:29 +0000 | [diff] [blame^] | 1 | .. SPDX-License-Identifier: GPL-2.0 |
| 2 | |
| 3 | Multiple Mount Protection |
| 4 | ------------------------- |
| 5 | |
| 6 | Multiple mount protection (MMP) is a feature that protects the |
| 7 | filesystem against multiple hosts trying to use the filesystem |
| 8 | simultaneously. When a filesystem is opened (for mounting, or fsck, |
| 9 | etc.), the MMP code running on the node (call it node A) checks a |
| 10 | sequence number. If the sequence number is EXT4\_MMP\_SEQ\_CLEAN, the |
| 11 | open continues. If the sequence number is EXT4\_MMP\_SEQ\_FSCK, then |
| 12 | fsck is (hopefully) running, and open fails immediately. Otherwise, the |
| 13 | open code will wait for twice the specified MMP check interval and check |
| 14 | the sequence number again. If the sequence number has changed, then the |
| 15 | filesystem is active on another machine and the open fails. If the MMP |
| 16 | code passes all of those checks, a new MMP sequence number is generated |
| 17 | and written to the MMP block, and the mount proceeds. |
| 18 | |
| 19 | While the filesystem is live, the kernel sets up a timer to re-check the |
| 20 | MMP block at the specified MMP check interval. To perform the re-check, |
| 21 | the MMP sequence number is re-read; if it does not match the in-memory |
| 22 | MMP sequence number, then another node (node B) has mounted the |
| 23 | filesystem, and node A remounts the filesystem read-only. If the |
| 24 | sequence numbers match, the sequence number is incremented both in |
| 25 | memory and on disk, and the re-check is complete. |
| 26 | |
| 27 | The hostname and device filename are written into the MMP block whenever |
| 28 | an open operation succeeds. The MMP code does not use these values; they |
| 29 | are provided purely for informational purposes. |
| 30 | |
| 31 | The checksum is calculated against the FS UUID and the MMP structure. |
| 32 | The MMP structure (``struct mmp_struct``) is as follows: |
| 33 | |
| 34 | .. list-table:: |
| 35 | :widths: 8 12 20 40 |
| 36 | :header-rows: 1 |
| 37 | |
| 38 | * - Offset |
| 39 | - Type |
| 40 | - Name |
| 41 | - Description |
| 42 | * - 0x0 |
| 43 | - \_\_le32 |
| 44 | - mmp\_magic |
| 45 | - Magic number for MMP, 0x004D4D50 (“MMP”). |
| 46 | * - 0x4 |
| 47 | - \_\_le32 |
| 48 | - mmp\_seq |
| 49 | - Sequence number, updated periodically. |
| 50 | * - 0x8 |
| 51 | - \_\_le64 |
| 52 | - mmp\_time |
| 53 | - Time that the MMP block was last updated. |
| 54 | * - 0x10 |
| 55 | - char[64] |
| 56 | - mmp\_nodename |
| 57 | - Hostname of the node that opened the filesystem. |
| 58 | * - 0x50 |
| 59 | - char[32] |
| 60 | - mmp\_bdevname |
| 61 | - Block device name of the filesystem. |
| 62 | * - 0x70 |
| 63 | - \_\_le16 |
| 64 | - mmp\_check\_interval |
| 65 | - The MMP re-check interval, in seconds. |
| 66 | * - 0x72 |
| 67 | - \_\_le16 |
| 68 | - mmp\_pad1 |
| 69 | - Zero. |
| 70 | * - 0x74 |
| 71 | - \_\_le32[226] |
| 72 | - mmp\_pad2 |
| 73 | - Zero. |
| 74 | * - 0x3FC |
| 75 | - \_\_le32 |
| 76 | - mmp\_checksum |
| 77 | - Checksum of the MMP block. |