Re: [PATCH] hfsplus: Add module parameter to enable force writes

From: Viacheslav Dubeyko
Date: Fri Dec 02 2022 - 15:38:35 EST




> On Dec 1, 2022, at 10:01 PM, Aditya Garg <gargaditya08@xxxxxxxx> wrote:
>
> From: Aditya Garg <gargaditya08@xxxxxxxx>
>
> This patch enables users to permanently enable writes of HFS+ locked
> and/or journaled volumes using a module parameter.
>
> Why module parameter?
> Reason being, its not convenient to manually mount the volume with force
> everytime. There are use cases which are fine with force enabling writes
> on journaled volumes. I've seen many on various online forums and I am one
> of them as well.
>
> Isn't it risky?
> Yes obviously it is, as the driver itself warns users for the same. But
> any user using the parameter obviously shall be well aware of the risks
> involved. To be honest, I've been writing on a 100Gb journaled volume for
> a few days, including both large and small files, and haven't faced any
> corruption yet.
>

If you created HFS+ volume under Linux, then you never have journal
and problem of journal replay (even if you created journaled volume).
So, I see the only one case when you have journal with transactions.
You are using HFS+ volume in Linux and Mac OS X. It means that
Mac OS X can create transactions in the journal and Linux needs
to manage it somehow.

Even if you don’t see any corruptions after such short testing, then
it doesn’t mean that you are safe. The key trouble that you can
silently lose the data because some metadata state could sit
in the journal and no replay operation has happened. Yes, you can
ignore the transactions in the journal and continue to store data and
modify metadata. But if journal still contain valid transactions, then
mount operation under Mac OS X will replay journal. And it sounds
that journal replay under Mac OS X can corrupt metadata and data
state that was modified/created under Linux.

So, I believe that your suggestion is slightly dangerous because
people loves to make mistakes and really hates to lose data.

Thanks,
Slava.

> Signed-off-by: Aditya Garg <gargaditya08@xxxxxxxx>
> ---
> fs/hfsplus/super.c | 46 ++++++++++++++++++++++++++++++++++++----------
> 1 file changed, 36 insertions(+), 10 deletions(-)
>
> diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
> index 122ed89eb..2367a2407 100644
> --- a/fs/hfsplus/super.c
> +++ b/fs/hfsplus/super.c
> @@ -24,6 +24,16 @@ static void hfsplus_free_inode(struct inode *inode);
> #include "hfsplus_fs.h"
> #include "xattr.h"
>
> +static unsigned int force_journaled_rw;
> +module_param(force_journaled_rw, uint, 0644);
> +MODULE_PARM_DESC(force_journaled_rw, "Force enable writes on Journaled HFS+ volumes. "
> + "([0] = disabled, 1 = enabled)");
> +
> +static unsigned int force_locked_rw;
> +module_param(force_locked_rw, uint, 0644);
> +MODULE_PARM_DESC(force_locked_rw, "Force enable writes on locked HFS+ volumes. "
> + "([0] = disabled, 1 = enabled)");
> +
> static int hfsplus_system_read_inode(struct inode *inode)
> {
> struct hfsplus_vh *vhdr = HFSPLUS_SB(inode->i_sb)->s_vhdr;
> @@ -346,14 +356,22 @@ static int hfsplus_remount(struct super_block *sb, int *flags, char *data)
> /* nothing */
> } else if (vhdr->attributes &
> cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) {
> - pr_warn("filesystem is marked locked, leaving read-only.\n");
> - sb->s_flags |= SB_RDONLY;
> - *flags |= SB_RDONLY;
> + if (force_locked_rw) {
> + pr_warn("filesystem is marked locked, but writes have been force enabled.\n");
> + } else {
> + pr_warn("filesystem is marked locked, leaving read-only.\n");
> + sb->s_flags |= SB_RDONLY;
> + *flags |= SB_RDONLY;
> + }
> } else if (vhdr->attributes &
> cpu_to_be32(HFSPLUS_VOL_JOURNALED)) {
> - pr_warn("filesystem is marked journaled, leaving read-only.\n");
> - sb->s_flags |= SB_RDONLY;
> - *flags |= SB_RDONLY;
> + if (force_journaled_rw) {
> + pr_warn("filesystem is marked journaled, but writes have been force enabled.\n");
> + } else {
> + pr_warn("filesystem is marked journaled, leaving read-only.\n");
> + sb->s_flags |= SB_RDONLY;
> + *flags |= SB_RDONLY;
> + }
> }
> }
> return 0;
> @@ -459,12 +477,20 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
> } else if (test_and_clear_bit(HFSPLUS_SB_FORCE, &sbi->flags)) {
> /* nothing */
> } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) {
> - pr_warn("Filesystem is marked locked, mounting read-only.\n");
> - sb->s_flags |= SB_RDONLY;
> + if (force_locked_rw) {
> + pr_warn("Filesystem is marked locked, but writes have been force enabled.\n");
> + } else {
> + pr_warn("Filesystem is marked locked, mounting read-only.\n");
> + sb->s_flags |= SB_RDONLY;
> + }
> } else if ((vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) &&
> !sb_rdonly(sb)) {
> - pr_warn("write access to a journaled filesystem is not supported, use the force option at your own risk, mounting read-only.\n");
> - sb->s_flags |= SB_RDONLY;
> + if (force_journaled_rw) {
> + pr_warn("write access to a journaled filesystem is not supported, but has been force enabled.\n");
> + } else {
> + pr_warn("write access to a journaled filesystem is not supported, use the force option at your own risk, mounting read-only.\n");
> + sb->s_flags |= SB_RDONLY;
> + }
> }
>
> err = -EINVAL;
> --
> 2.38.1
>