summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara2015-12-07 20:35:49 +0100
committerTheodore Ts'o2015-12-07 20:35:49 +0100
commite74031fd7ed0989da8a80364b4d269a57e9c164a (patch)
tree82a6520202b1e4637fbfebd7088058bd42c2e5cd
parentext4: fix races of writeback with punch hole and zero range (diff)
downloadkernel-qcow2-linux-e74031fd7ed0989da8a80364b4d269a57e9c164a.tar.gz
kernel-qcow2-linux-e74031fd7ed0989da8a80364b4d269a57e9c164a.tar.xz
kernel-qcow2-linux-e74031fd7ed0989da8a80364b4d269a57e9c164a.zip
ext4: document lock ordering
We have enough locks that it's probably worth documenting the lock ordering rules we have in ext4. Signed-off-by: Jan Kara <jack@suse.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-rw-r--r--fs/ext4/super.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 493370e6590e..486e869bd583 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -80,6 +80,36 @@ static void ext4_destroy_lazyinit_thread(void);
static void ext4_unregister_li_request(struct super_block *sb);
static void ext4_clear_request_list(void);
+/*
+ * Lock ordering
+ *
+ * Note the difference between i_mmap_sem (EXT4_I(inode)->i_mmap_sem) and
+ * i_mmap_rwsem (inode->i_mmap_rwsem)!
+ *
+ * page fault path:
+ * mmap_sem -> sb_start_pagefault -> i_mmap_sem (r) -> transaction start ->
+ * page lock -> i_data_sem (rw)
+ *
+ * buffered write path:
+ * sb_start_write -> i_mutex -> mmap_sem
+ * sb_start_write -> i_mutex -> transaction start -> page lock ->
+ * i_data_sem (rw)
+ *
+ * truncate:
+ * sb_start_write -> i_mutex -> EXT4_STATE_DIOREAD_LOCK (w) -> i_mmap_sem (w) ->
+ * i_mmap_rwsem (w) -> page lock
+ * sb_start_write -> i_mutex -> EXT4_STATE_DIOREAD_LOCK (w) -> i_mmap_sem (w) ->
+ * transaction start -> i_data_sem (rw)
+ *
+ * direct IO:
+ * sb_start_write -> i_mutex -> EXT4_STATE_DIOREAD_LOCK (r) -> mmap_sem
+ * sb_start_write -> i_mutex -> EXT4_STATE_DIOREAD_LOCK (r) ->
+ * transaction start -> i_data_sem (rw)
+ *
+ * writepages:
+ * transaction start -> page lock(s) -> i_data_sem (rw)
+ */
+
#if !defined(CONFIG_EXT2_FS) && !defined(CONFIG_EXT2_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT2)
static struct file_system_type ext2_fs_type = {
.owner = THIS_MODULE,