aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/ext4.h
diff options
context:
space:
mode:
authorJohann Lombardi <johann@whamcloud.com>2011-05-24 18:31:25 -0400
committerTheodore Ts'o <tytso@mit.edu>2011-05-24 18:31:25 -0400
commitc5e06d101aaf72f1f2192a661414459775e9bd74 (patch)
tree96d05d41be2bfea6d51be915ce196f033a5d9bf3 /fs/ext4/ext4.h
parentd02a9391f79cab65cde74cd9e8ccd2290a565229 (diff)
ext4: add support for multiple mount protection
Prevent an ext4 filesystem from being mounted multiple times. A sequence number is stored on disk and is periodically updated (every 5 seconds by default) by a mounted filesystem. At mount time, we now wait for s_mmp_update_interval seconds to make sure that the MMP sequence does not change. In case of failure, the nodename, bdevname and the time at which the MMP block was last updated is displayed. Signed-off-by: Andreas Dilger <adilger@whamcloud.com> Signed-off-by: Johann Lombardi <johann@whamcloud.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/ext4.h')
-rw-r--r--fs/ext4/ext4.h76
1 files changed, 74 insertions, 2 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 65fe1dc0c750..c0c56c9d5933 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1028,7 +1028,7 @@ struct ext4_super_block {
1028 __le16 s_want_extra_isize; /* New inodes should reserve # bytes */ 1028 __le16 s_want_extra_isize; /* New inodes should reserve # bytes */
1029 __le32 s_flags; /* Miscellaneous flags */ 1029 __le32 s_flags; /* Miscellaneous flags */
1030 __le16 s_raid_stride; /* RAID stride */ 1030 __le16 s_raid_stride; /* RAID stride */
1031 __le16 s_mmp_interval; /* # seconds to wait in MMP checking */ 1031 __le16 s_mmp_update_interval; /* # seconds to wait in MMP checking */
1032 __le64 s_mmp_block; /* Block for multi-mount protection */ 1032 __le64 s_mmp_block; /* Block for multi-mount protection */
1033 __le32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/ 1033 __le32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/
1034 __u8 s_log_groups_per_flex; /* FLEX_BG group size */ 1034 __u8 s_log_groups_per_flex; /* FLEX_BG group size */
@@ -1204,6 +1204,9 @@ struct ext4_sb_info {
1204 struct ext4_li_request *s_li_request; 1204 struct ext4_li_request *s_li_request;
1205 /* Wait multiplier for lazy initialization thread */ 1205 /* Wait multiplier for lazy initialization thread */
1206 unsigned int s_li_wait_mult; 1206 unsigned int s_li_wait_mult;
1207
1208 /* Kernel thread for multiple mount protection */
1209 struct task_struct *s_mmp_tsk;
1207}; 1210};
1208 1211
1209static inline struct ext4_sb_info *EXT4_SB(struct super_block *sb) 1212static inline struct ext4_sb_info *EXT4_SB(struct super_block *sb)
@@ -1375,7 +1378,8 @@ static inline void ext4_clear_state_flags(struct ext4_inode_info *ei)
1375 EXT4_FEATURE_INCOMPAT_META_BG| \ 1378 EXT4_FEATURE_INCOMPAT_META_BG| \
1376 EXT4_FEATURE_INCOMPAT_EXTENTS| \ 1379 EXT4_FEATURE_INCOMPAT_EXTENTS| \
1377 EXT4_FEATURE_INCOMPAT_64BIT| \ 1380 EXT4_FEATURE_INCOMPAT_64BIT| \
1378 EXT4_FEATURE_INCOMPAT_FLEX_BG) 1381 EXT4_FEATURE_INCOMPAT_FLEX_BG| \
1382 EXT4_FEATURE_INCOMPAT_MMP)
1379#define EXT4_FEATURE_RO_COMPAT_SUPP (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \ 1383#define EXT4_FEATURE_RO_COMPAT_SUPP (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \
1380 EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \ 1384 EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \
1381 EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \ 1385 EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \
@@ -1627,6 +1631,67 @@ struct ext4_features {
1627}; 1631};
1628 1632
1629/* 1633/*
1634 * This structure will be used for multiple mount protection. It will be
1635 * written into the block number saved in the s_mmp_block field in the
1636 * superblock. Programs that check MMP should assume that if
1637 * SEQ_FSCK (or any unknown code above SEQ_MAX) is present then it is NOT safe
1638 * to use the filesystem, regardless of how old the timestamp is.
1639 */
1640#define EXT4_MMP_MAGIC 0x004D4D50U /* ASCII for MMP */
1641#define EXT4_MMP_SEQ_CLEAN 0xFF4D4D50U /* mmp_seq value for clean unmount */
1642#define EXT4_MMP_SEQ_FSCK 0xE24D4D50U /* mmp_seq value when being fscked */
1643#define EXT4_MMP_SEQ_MAX 0xE24D4D4FU /* maximum valid mmp_seq value */
1644
1645struct mmp_struct {
1646 __le32 mmp_magic; /* Magic number for MMP */
1647 __le32 mmp_seq; /* Sequence no. updated periodically */
1648
1649 /*
1650 * mmp_time, mmp_nodename & mmp_bdevname are only used for information
1651 * purposes and do not affect the correctness of the algorithm
1652 */
1653 __le64 mmp_time; /* Time last updated */
1654 char mmp_nodename[64]; /* Node which last updated MMP block */
1655 char mmp_bdevname[32]; /* Bdev which last updated MMP block */
1656
1657 /*
1658 * mmp_check_interval is used to verify if the MMP block has been
1659 * updated on the block device. The value is updated based on the
1660 * maximum time to write the MMP block during an update cycle.
1661 */
1662 __le16 mmp_check_interval;
1663
1664 __le16 mmp_pad1;
1665 __le32 mmp_pad2[227];
1666};
1667
1668/* arguments passed to the mmp thread */
1669struct mmpd_data {
1670 struct buffer_head *bh; /* bh from initial read_mmp_block() */
1671 struct super_block *sb; /* super block of the fs */
1672};
1673
1674/*
1675 * Check interval multiplier
1676 * The MMP block is written every update interval and initially checked every
1677 * update interval x the multiplier (the value is then adapted based on the
1678 * write latency). The reason is that writes can be delayed under load and we
1679 * don't want readers to incorrectly assume that the filesystem is no longer
1680 * in use.
1681 */
1682#define EXT4_MMP_CHECK_MULT 2UL
1683
1684/*
1685 * Minimum interval for MMP checking in seconds.
1686 */
1687#define EXT4_MMP_MIN_CHECK_INTERVAL 5UL
1688
1689/*
1690 * Maximum interval for MMP checking in seconds.
1691 */
1692#define EXT4_MMP_MAX_CHECK_INTERVAL 300UL
1693
1694/*
1630 * Function prototypes 1695 * Function prototypes
1631 */ 1696 */
1632 1697
@@ -1800,6 +1865,10 @@ extern void __ext4_warning(struct super_block *, const char *, unsigned int,
1800 __LINE__, ## message) 1865 __LINE__, ## message)
1801extern void ext4_msg(struct super_block *, const char *, const char *, ...) 1866extern void ext4_msg(struct super_block *, const char *, const char *, ...)
1802 __attribute__ ((format (printf, 3, 4))); 1867 __attribute__ ((format (printf, 3, 4)));
1868extern void __dump_mmp_msg(struct super_block *, struct mmp_struct *mmp,
1869 const char *, unsigned int, const char *);
1870#define dump_mmp_msg(sb, mmp, msg) __dump_mmp_msg(sb, mmp, __func__, \
1871 __LINE__, msg)
1803extern void __ext4_grp_locked_error(const char *, unsigned int, \ 1872extern void __ext4_grp_locked_error(const char *, unsigned int, \
1804 struct super_block *, ext4_group_t, \ 1873 struct super_block *, ext4_group_t, \
1805 unsigned long, ext4_fsblk_t, \ 1874 unsigned long, ext4_fsblk_t, \
@@ -2104,6 +2173,9 @@ extern int ext4_bio_write_page(struct ext4_io_submit *io,
2104 int len, 2173 int len,
2105 struct writeback_control *wbc); 2174 struct writeback_control *wbc);
2106 2175
2176/* mmp.c */
2177extern int ext4_multi_mount_protect(struct super_block *, ext4_fsblk_t);
2178
2107/* BH_Uninit flag: blocks are allocated but uninitialized on disk */ 2179/* BH_Uninit flag: blocks are allocated but uninitialized on disk */
2108enum ext4_state_bits { 2180enum ext4_state_bits {
2109 BH_Uninit /* blocks are allocated but uninitialized on disk */ 2181 BH_Uninit /* blocks are allocated but uninitialized on disk */