From: Darrick J. Wong <djwong@xxxxxxxxxx> There's no way to return an error from the op_init function and have libfuse tear down the mount, aside from calling fuse_session_exit and aborting the program. Even that's not useful, because libfuse has already daemonized us at that point, so the error messages are screamed into a void. Move the code that clears the VALID_FS bit to main() so that we can abort the mount with a useful error message if that write fails. Cc: <linux-ext4@xxxxxxxxxxxxxxx> # v1.43 Fixes: 81cbf1ef4f5dab ("misc: add fuse2fs, a FUSE server for e2fsprogs") Signed-off-by: "Darrick J. Wong" <djwong@xxxxxxxxxx> --- misc/fuse2fs.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c index d670c5db1206f2..c201f95e771b85 100644 --- a/misc/fuse2fs.c +++ b/misc/fuse2fs.c @@ -907,7 +907,6 @@ static void *op_init(struct fuse_conn_info *conn struct fuse_context *ctxt = fuse_get_context(); struct fuse2fs *ff = (struct fuse2fs *)ctxt->private_data; ext2_filsys fs; - errcode_t err; if (ff->magic != FUSE2FS_MAGIC) { translate_error(global_fs, 0, EXT2_ET_BAD_MAGIC); @@ -939,15 +938,6 @@ static void *op_init(struct fuse_conn_info *conn if (ff->debug) cfg->debug = 1; #endif - if (fs->flags & EXT2_FLAG_RW) { - fs->super->s_mnt_count++; - ext2fs_set_tstamp(fs->super, s_mtime, time(NULL)); - fs->super->s_state &= ~EXT2_VALID_FS; - ext2fs_mark_super_dirty(fs); - err = ext2fs_flush2(fs, 0); - if (err) - translate_error(fs, 0, err); - } if (ff->kernel) { char uuid[UUID_STR_SIZE]; @@ -4733,6 +4723,10 @@ int main(int argc, char *argv[]) goto out; } + /* + * ext4 can't do COW of shared blocks, so if the feature is enabled, + * we must force ro mode. + */ if (ext2fs_has_feature_shared_blocks(global_fs->super)) fctx.ro = 1; @@ -4796,6 +4790,20 @@ int main(int argc, char *argv[]) goto out; } + /* Clear the valid flag so that an unclean shutdown forces a fsck */ + if (global_fs->flags & EXT2_FLAG_RW) { + global_fs->super->s_mnt_count++; + ext2fs_set_tstamp(global_fs->super, s_mtime, time(NULL)); + global_fs->super->s_state &= ~EXT2_VALID_FS; + ext2fs_mark_super_dirty(global_fs); + err = ext2fs_flush2(global_fs, 0); + if (err) { + translate_error(global_fs, 0, err); + ret |= 32; + goto out; + } + } + /* Initialize generation counter */ get_random_bytes(&fctx.next_generation, sizeof(unsigned int));