mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	ext4: check superblock mapped prior to committing
This patch attempts to close a hole leading to a BUG seen with hot
removals during writes [1].
A block device (NVME namespace in this test case) is formatted to EXT4
without partitions. It's mounted and write I/O is run to a file, then
the device is hot removed from the slot. The superblock attempts to be
written to the drive which is no longer present.
The typical chain of events leading to the BUG:
ext4_commit_super()
  __sync_dirty_buffer()
    submit_bh()
      submit_bh_wbc()
        BUG_ON(!buffer_mapped(bh));
This fix checks for the superblock's buffer head being mapped prior to
syncing.
[1] https://www.spinics.net/lists/linux-ext4/msg56527.html
Signed-off-by: Jon Derrick <jonathan.derrick@intel.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Cc: stable@kernel.org
			
			
This commit is contained in:
		
							parent
							
								
									bfe0a5f47a
								
							
						
					
					
						commit
						a17712c8e4
					
				
					 1 changed files with 8 additions and 0 deletions
				
			
		| 
						 | 
					@ -4808,6 +4808,14 @@ static int ext4_commit_super(struct super_block *sb, int sync)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!sbh || block_device_ejected(sb))
 | 
						if (!sbh || block_device_ejected(sb))
 | 
				
			||||||
		return error;
 | 
							return error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * The superblock bh should be mapped, but it might not be if the
 | 
				
			||||||
 | 
						 * device was hot-removed. Not much we can do but fail the I/O.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (!buffer_mapped(sbh))
 | 
				
			||||||
 | 
							return error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * If the file system is mounted read-only, don't update the
 | 
						 * If the file system is mounted read-only, don't update the
 | 
				
			||||||
	 * superblock write time.  This avoids updating the superblock
 | 
						 * superblock write time.  This avoids updating the superblock
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue