ext4: reflect error codes from ext4_multi_mount_protect() to its callers
authorTheodore Ts'o <tytso@mit.edu>
Fri, 28 Apr 2023 02:49:34 +0000 (22:49 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Fri, 28 Apr 2023 16:56:40 +0000 (12:56 -0400)
This will allow more fine-grained errno codes to be returned by the
mount system call.

Cc: Andreas Dilger <adilger.kernel@dilger.ca>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
fs/ext4/mmp.c
fs/ext4/super.c

index 4681fff..4022bc7 100644 (file)
@@ -282,6 +282,7 @@ int ext4_multi_mount_protect(struct super_block *sb,
        if (mmp_block < le32_to_cpu(es->s_first_data_block) ||
            mmp_block >= ext4_blocks_count(es)) {
                ext4_warning(sb, "Invalid MMP block in superblock");
+               retval = -EINVAL;
                goto failed;
        }
 
@@ -307,6 +308,7 @@ int ext4_multi_mount_protect(struct super_block *sb,
 
        if (seq == EXT4_MMP_SEQ_FSCK) {
                dump_mmp_msg(sb, mmp, "fsck is running on the filesystem");
+               retval = -EBUSY;
                goto failed;
        }
 
@@ -320,6 +322,7 @@ int ext4_multi_mount_protect(struct super_block *sb,
 
        if (schedule_timeout_interruptible(HZ * wait_time) != 0) {
                ext4_warning(sb, "MMP startup interrupted, failing mount\n");
+               retval = -ETIMEDOUT;
                goto failed;
        }
 
@@ -330,6 +333,7 @@ int ext4_multi_mount_protect(struct super_block *sb,
        if (seq != le32_to_cpu(mmp->mmp_seq)) {
                dump_mmp_msg(sb, mmp,
                             "Device is already active on another node.");
+               retval = -EBUSY;
                goto failed;
        }
 
@@ -349,6 +353,7 @@ skip:
         */
        if (schedule_timeout_interruptible(HZ * wait_time) != 0) {
                ext4_warning(sb, "MMP startup interrupted, failing mount");
+               retval = -ETIMEDOUT;
                goto failed;
        }
 
@@ -359,6 +364,7 @@ skip:
        if (seq != le32_to_cpu(mmp->mmp_seq)) {
                dump_mmp_msg(sb, mmp,
                             "Device is already active on another node.");
+               retval = -EBUSY;
                goto failed;
        }
 
@@ -378,6 +384,7 @@ skip:
                EXT4_SB(sb)->s_mmp_tsk = NULL;
                ext4_warning(sb, "Unable to create kmmpd thread for %s.",
                             sb->s_id);
+               retval = -ENOMEM;
                goto failed;
        }
 
@@ -385,5 +392,5 @@ skip:
 
 failed:
        brelse(bh);
-       return 1;
+       return retval;
 }
index 8ed6450..c8ae6b7 100644 (file)
@@ -5328,9 +5328,11 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
                          ext4_has_feature_orphan_present(sb) ||
                          ext4_has_feature_journal_needs_recovery(sb));
 
-       if (ext4_has_feature_mmp(sb) && !sb_rdonly(sb))
-               if (ext4_multi_mount_protect(sb, le64_to_cpu(es->s_mmp_block)))
+       if (ext4_has_feature_mmp(sb) && !sb_rdonly(sb)) {
+               err = ext4_multi_mount_protect(sb, le64_to_cpu(es->s_mmp_block));
+               if (err)
                        goto failed_mount3a;
+       }
 
        /*
         * The first inode we look at is the journal inode.  Don't try
@@ -6565,12 +6567,12 @@ static int __ext4_remount(struct fs_context *fc, struct super_block *sb)
                                goto restore_opts;
 
                        sb->s_flags &= ~SB_RDONLY;
-                       if (ext4_has_feature_mmp(sb))
-                               if (ext4_multi_mount_protect(sb,
-                                               le64_to_cpu(es->s_mmp_block))) {
-                                       err = -EROFS;
+                       if (ext4_has_feature_mmp(sb)) {
+                               err = ext4_multi_mount_protect(sb,
+                                               le64_to_cpu(es->s_mmp_block));
+                               if (err)
                                        goto restore_opts;
-                               }
+                       }
 #ifdef CONFIG_QUOTA
                        enable_quota = 1;
 #endif