Skip to content

Commit 0a1b2f5

Browse files
LiBaokun96tytso
authored andcommitted
ext4: add ext4_emergency_state() helper function
Since both SHUTDOWN and EMERGENCY_RO are emergency states of the ext4 file system, and they are checked in similar locations, we have added a helper function, ext4_emergency_state(), to determine whether the current file system is in one of these two emergency states. Then, replace calls to ext4_forced_shutdown() with ext4_emergency_state() in those functions that could potentially trigger write operations. Signed-off-by: Baokun Li <[email protected]> Reviewed-by: Jan Kara <[email protected]> Reviewed-by: Zhang Yi <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Theodore Ts'o <[email protected]>
1 parent f3054e5 commit 0a1b2f5

File tree

12 files changed

+91
-61
lines changed

12 files changed

+91
-61
lines changed

fs/ext4/ext4.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2252,6 +2252,15 @@ static inline int ext4_emergency_ro(struct super_block *sb)
22522252
return test_bit(EXT4_FLAGS_EMERGENCY_RO, &EXT4_SB(sb)->s_ext4_flags);
22532253
}
22542254

2255+
static inline int ext4_emergency_state(struct super_block *sb)
2256+
{
2257+
if (unlikely(ext4_forced_shutdown(sb)))
2258+
return -EIO;
2259+
if (unlikely(ext4_emergency_ro(sb)))
2260+
return -EROFS;
2261+
return 0;
2262+
}
2263+
22552264
/*
22562265
* Default values for user and/or group using reserved blocks
22572266
*/

fs/ext4/ext4_jbd2.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,14 @@ static void ext4_put_nojournal(handle_t *handle)
6363
*/
6464
static int ext4_journal_check_start(struct super_block *sb)
6565
{
66+
int ret;
6667
journal_t *journal;
6768

6869
might_sleep();
6970

70-
if (unlikely(ext4_forced_shutdown(sb)))
71-
return -EIO;
71+
ret = ext4_emergency_state(sb);
72+
if (unlikely(ret))
73+
return ret;
7274

7375
if (WARN_ON_ONCE(sb_rdonly(sb)))
7476
return -EROFS;

fs/ext4/file.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -688,10 +688,12 @@ ext4_dax_write_iter(struct kiocb *iocb, struct iov_iter *from)
688688
static ssize_t
689689
ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
690690
{
691+
int ret;
691692
struct inode *inode = file_inode(iocb->ki_filp);
692693

693-
if (unlikely(ext4_forced_shutdown(inode->i_sb)))
694-
return -EIO;
694+
ret = ext4_emergency_state(inode->i_sb);
695+
if (unlikely(ret))
696+
return ret;
695697

696698
#ifdef CONFIG_FS_DAX
697699
if (IS_DAX(inode))
@@ -700,7 +702,6 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
700702

701703
if (iocb->ki_flags & IOCB_ATOMIC) {
702704
size_t len = iov_iter_count(from);
703-
int ret;
704705

705706
if (len < EXT4_SB(inode->i_sb)->s_awu_min ||
706707
len > EXT4_SB(inode->i_sb)->s_awu_max)
@@ -803,11 +804,16 @@ static const struct vm_operations_struct ext4_file_vm_ops = {
803804

804805
static int ext4_file_mmap(struct file *file, struct vm_area_struct *vma)
805806
{
807+
int ret;
806808
struct inode *inode = file->f_mapping->host;
807809
struct dax_device *dax_dev = EXT4_SB(inode->i_sb)->s_daxdev;
808810

809-
if (unlikely(ext4_forced_shutdown(inode->i_sb)))
810-
return -EIO;
811+
if (file->f_mode & FMODE_WRITE)
812+
ret = ext4_emergency_state(inode->i_sb);
813+
else
814+
ret = ext4_forced_shutdown(inode->i_sb) ? -EIO : 0;
815+
if (unlikely(ret))
816+
return ret;
811817

812818
/*
813819
* We don't support synchronous mappings for non-DAX files and
@@ -881,8 +887,12 @@ static int ext4_file_open(struct inode *inode, struct file *filp)
881887
{
882888
int ret;
883889

884-
if (unlikely(ext4_forced_shutdown(inode->i_sb)))
885-
return -EIO;
890+
if (filp->f_mode & FMODE_WRITE)
891+
ret = ext4_emergency_state(inode->i_sb);
892+
else
893+
ret = ext4_forced_shutdown(inode->i_sb) ? -EIO : 0;
894+
if (unlikely(ret))
895+
return ret;
886896

887897
ret = ext4_sample_last_mounted(inode->i_sb, filp->f_path.mnt);
888898
if (ret)

fs/ext4/fsync.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -132,20 +132,16 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
132132
bool needs_barrier = false;
133133
struct inode *inode = file->f_mapping->host;
134134

135-
if (unlikely(ext4_forced_shutdown(inode->i_sb)))
136-
return -EIO;
135+
ret = ext4_emergency_state(inode->i_sb);
136+
if (unlikely(ret))
137+
return ret;
137138

138139
ASSERT(ext4_journal_current_handle() == NULL);
139140

140141
trace_ext4_sync_file_enter(file, datasync);
141142

142-
if (sb_rdonly(inode->i_sb)) {
143-
/* Make sure that we read updated s_ext4_flags value */
144-
smp_rmb();
145-
if (ext4_forced_shutdown(inode->i_sb))
146-
ret = -EROFS;
143+
if (sb_rdonly(inode->i_sb))
147144
goto out;
148-
}
149145

150146
if (!EXT4_SB(inode->i_sb)->s_journal) {
151147
ret = ext4_fsync_nojournal(file, start, end, datasync,

fs/ext4/ialloc.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -951,8 +951,9 @@ struct inode *__ext4_new_inode(struct mnt_idmap *idmap,
951951
sb = dir->i_sb;
952952
sbi = EXT4_SB(sb);
953953

954-
if (unlikely(ext4_forced_shutdown(sb)))
955-
return ERR_PTR(-EIO);
954+
ret2 = ext4_emergency_state(sb);
955+
if (unlikely(ret2))
956+
return ERR_PTR(ret2);
956957

957958
ngroups = ext4_get_groups_count(sb);
958959
trace_ext4_request_inode(dir, mode);

fs/ext4/inline.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ static void ext4_write_inline_data(struct inode *inode, struct ext4_iloc *iloc,
233233
struct ext4_inode *raw_inode;
234234
int cp_len = 0;
235235

236-
if (unlikely(ext4_forced_shutdown(inode->i_sb)))
236+
if (unlikely(ext4_emergency_state(inode->i_sb)))
237237
return;
238238

239239
BUG_ON(!EXT4_I(inode)->i_inline_off);

fs/ext4/inode.c

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,8 +1150,9 @@ static int ext4_write_begin(struct file *file, struct address_space *mapping,
11501150
pgoff_t index;
11511151
unsigned from, to;
11521152

1153-
if (unlikely(ext4_forced_shutdown(inode->i_sb)))
1154-
return -EIO;
1153+
ret = ext4_emergency_state(inode->i_sb);
1154+
if (unlikely(ret))
1155+
return ret;
11551156

11561157
trace_ext4_write_begin(inode, pos, len);
11571158
/*
@@ -2274,7 +2275,7 @@ static int mpage_map_and_submit_extent(handle_t *handle,
22742275
if (err < 0) {
22752276
struct super_block *sb = inode->i_sb;
22762277

2277-
if (ext4_forced_shutdown(sb))
2278+
if (ext4_emergency_state(sb))
22782279
goto invalidate_dirty_pages;
22792280
/*
22802281
* Let the uper layers retry transient errors.
@@ -2600,10 +2601,9 @@ static int ext4_do_writepages(struct mpage_da_data *mpd)
26002601
* *never* be called, so if that ever happens, we would want
26012602
* the stack trace.
26022603
*/
2603-
if (unlikely(ext4_forced_shutdown(mapping->host->i_sb))) {
2604-
ret = -EROFS;
2604+
ret = ext4_emergency_state(mapping->host->i_sb);
2605+
if (unlikely(ret))
26052606
goto out_writepages;
2606-
}
26072607

26082608
/*
26092609
* If we have inline data and arrive here, it means that
@@ -2818,8 +2818,9 @@ static int ext4_writepages(struct address_space *mapping,
28182818
int ret;
28192819
int alloc_ctx;
28202820

2821-
if (unlikely(ext4_forced_shutdown(sb)))
2822-
return -EIO;
2821+
ret = ext4_emergency_state(sb);
2822+
if (unlikely(ret))
2823+
return ret;
28232824

28242825
alloc_ctx = ext4_writepages_down_read(sb);
28252826
ret = ext4_do_writepages(&mpd);
@@ -2859,8 +2860,9 @@ static int ext4_dax_writepages(struct address_space *mapping,
28592860
struct inode *inode = mapping->host;
28602861
int alloc_ctx;
28612862

2862-
if (unlikely(ext4_forced_shutdown(inode->i_sb)))
2863-
return -EIO;
2863+
ret = ext4_emergency_state(inode->i_sb);
2864+
if (unlikely(ret))
2865+
return ret;
28642866

28652867
alloc_ctx = ext4_writepages_down_read(inode->i_sb);
28662868
trace_ext4_writepages(inode, wbc);
@@ -2916,8 +2918,9 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping,
29162918
pgoff_t index;
29172919
struct inode *inode = mapping->host;
29182920

2919-
if (unlikely(ext4_forced_shutdown(inode->i_sb)))
2920-
return -EIO;
2921+
ret = ext4_emergency_state(inode->i_sb);
2922+
if (unlikely(ret))
2923+
return ret;
29212924

29222925
index = pos >> PAGE_SHIFT;
29232926

@@ -5247,8 +5250,9 @@ int ext4_write_inode(struct inode *inode, struct writeback_control *wbc)
52475250
if (WARN_ON_ONCE(current->flags & PF_MEMALLOC))
52485251
return 0;
52495252

5250-
if (unlikely(ext4_forced_shutdown(inode->i_sb)))
5251-
return -EIO;
5253+
err = ext4_emergency_state(inode->i_sb);
5254+
if (unlikely(err))
5255+
return err;
52525256

52535257
if (EXT4_SB(inode->i_sb)->s_journal) {
52545258
if (ext4_journal_current_handle()) {
@@ -5370,8 +5374,9 @@ int ext4_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
53705374
const unsigned int ia_valid = attr->ia_valid;
53715375
bool inc_ivers = true;
53725376

5373-
if (unlikely(ext4_forced_shutdown(inode->i_sb)))
5374-
return -EIO;
5377+
error = ext4_emergency_state(inode->i_sb);
5378+
if (unlikely(error))
5379+
return error;
53755380

53765381
if (unlikely(IS_IMMUTABLE(inode)))
53775382
return -EPERM;
@@ -5815,9 +5820,10 @@ int ext4_mark_iloc_dirty(handle_t *handle,
58155820
{
58165821
int err = 0;
58175822

5818-
if (unlikely(ext4_forced_shutdown(inode->i_sb))) {
5823+
err = ext4_emergency_state(inode->i_sb);
5824+
if (unlikely(err)) {
58195825
put_bh(iloc->bh);
5820-
return -EIO;
5826+
return err;
58215827
}
58225828
ext4_fc_track_inode(handle, inode);
58235829

@@ -5841,8 +5847,9 @@ ext4_reserve_inode_write(handle_t *handle, struct inode *inode,
58415847
{
58425848
int err;
58435849

5844-
if (unlikely(ext4_forced_shutdown(inode->i_sb)))
5845-
return -EIO;
5850+
err = ext4_emergency_state(inode->i_sb);
5851+
if (unlikely(err))
5852+
return err;
58465853

58475854
err = ext4_get_inode_loc(inode, iloc);
58485855
if (!err) {

fs/ext4/mballoc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5653,7 +5653,7 @@ static inline void ext4_mb_show_pa(struct super_block *sb)
56535653
{
56545654
ext4_group_t i, ngroups;
56555655

5656-
if (ext4_forced_shutdown(sb))
5656+
if (ext4_emergency_state(sb))
56575657
return;
56585658

56595659
ngroups = ext4_get_groups_count(sb);
@@ -5687,7 +5687,7 @@ static void ext4_mb_show_ac(struct ext4_allocation_context *ac)
56875687
{
56885688
struct super_block *sb = ac->ac_sb;
56895689

5690-
if (ext4_forced_shutdown(sb))
5690+
if (ext4_emergency_state(sb))
56915691
return;
56925692

56935693
mb_debug(sb, "Can't allocate:"

fs/ext4/mmp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ static int kmmpd(void *data)
162162
memcpy(mmp->mmp_nodename, init_utsname()->nodename,
163163
sizeof(mmp->mmp_nodename));
164164

165-
while (!kthread_should_stop() && !ext4_forced_shutdown(sb)) {
165+
while (!kthread_should_stop() && !ext4_emergency_state(sb)) {
166166
if (!ext4_has_feature_mmp(sb)) {
167167
ext4_warning(sb, "kmmpd being stopped since MMP feature"
168168
" has been disabled.");

fs/ext4/namei.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3157,8 +3157,9 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry)
31573157
struct ext4_dir_entry_2 *de;
31583158
handle_t *handle = NULL;
31593159

3160-
if (unlikely(ext4_forced_shutdown(dir->i_sb)))
3161-
return -EIO;
3160+
retval = ext4_emergency_state(dir->i_sb);
3161+
if (unlikely(retval))
3162+
return retval;
31623163

31633164
/* Initialize quotas before so that eventual writes go in
31643165
* separate transaction */
@@ -3315,8 +3316,9 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
33153316
{
33163317
int retval;
33173318

3318-
if (unlikely(ext4_forced_shutdown(dir->i_sb)))
3319-
return -EIO;
3319+
retval = ext4_emergency_state(dir->i_sb);
3320+
if (unlikely(retval))
3321+
return retval;
33203322

33213323
trace_ext4_unlink_enter(dir, dentry);
33223324
/*
@@ -3382,8 +3384,9 @@ static int ext4_symlink(struct mnt_idmap *idmap, struct inode *dir,
33823384
struct fscrypt_str disk_link;
33833385
int retries = 0;
33843386

3385-
if (unlikely(ext4_forced_shutdown(dir->i_sb)))
3386-
return -EIO;
3387+
err = ext4_emergency_state(dir->i_sb);
3388+
if (unlikely(err))
3389+
return err;
33873390

33883391
err = fscrypt_prepare_symlink(dir, symname, len, dir->i_sb->s_blocksize,
33893392
&disk_link);
@@ -4205,8 +4208,9 @@ static int ext4_rename2(struct mnt_idmap *idmap,
42054208
{
42064209
int err;
42074210

4208-
if (unlikely(ext4_forced_shutdown(old_dir->i_sb)))
4209-
return -EIO;
4211+
err = ext4_emergency_state(old_dir->i_sb);
4212+
if (unlikely(err))
4213+
return err;
42104214

42114215
if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT))
42124216
return -EINVAL;

0 commit comments

Comments
 (0)