ext4: fix potential race between online resizing and write operations
[linux-block.git] / fs / ext4 / ext4.h
index 480badcf27832e10b849bd977071563b8bd70ac5..b51003f755684ec78789d9c70c5ccf2e111e053e 100644 (file)
@@ -1400,7 +1400,7 @@ struct ext4_sb_info {
        loff_t s_bitmap_maxbytes;       /* max bytes for bitmap files */
        struct buffer_head * s_sbh;     /* Buffer containing the super block */
        struct ext4_super_block *s_es;  /* Pointer to the super block in the buffer */
-       struct buffer_head **s_group_desc;
+       struct buffer_head * __rcu *s_group_desc;
        unsigned int s_mount_opt;
        unsigned int s_mount_opt2;
        unsigned int s_mount_flags;
@@ -1576,6 +1576,23 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
                 ino <= le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count));
 }
 
+/*
+ * Returns: sbi->field[index]
+ * Used to access an array element from the following sbi fields which require
+ * rcu protection to avoid dereferencing an invalid pointer due to reassignment
+ * - s_group_desc
+ * - s_group_info
+ * - s_flex_group
+ */
+#define sbi_array_rcu_deref(sbi, field, index)                            \
+({                                                                        \
+       typeof(*((sbi)->field)) _v;                                        \
+       rcu_read_lock();                                                   \
+       _v = ((typeof(_v)*)rcu_dereference((sbi)->field))[index];          \
+       rcu_read_unlock();                                                 \
+       _v;                                                                \
+})
+
 /*
  * Simulate_fail codes
  */
@@ -2730,6 +2747,7 @@ extern int ext4_generic_delete_entry(handle_t *handle,
 extern bool ext4_empty_dir(struct inode *inode);
 
 /* resize.c */
+extern void ext4_kvfree_array_rcu(void *to_free);
 extern int ext4_group_add(struct super_block *sb,
                                struct ext4_new_group_data *input);
 extern int ext4_group_extend(struct super_block *sb,