diff mbox series

kernel: force atomic renames in ubifs

Message ID 20220301191329.22329-1-zajec5@gmail.com
State Under Review
Delegated to: Rafał Miłecki
Headers show
Series kernel: force atomic renames in ubifs | expand

Commit Message

Rafał Miłecki March 1, 2022, 7:13 p.m. UTC
From: Rafał Miłecki <rafal@milecki.pl>

This deals with user-spaces apps that don't handle all syncing
correctly. It prevents user ending up with an empty file.

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
 .../510-ubifs-force-atomic-renames.patch      | 46 +++++++++++++++++++
 .../510-ubifs-force-atomic-renames.patch      | 46 +++++++++++++++++++
 2 files changed, 92 insertions(+)
 create mode 100644 target/linux/generic/pending-5.10/510-ubifs-force-atomic-renames.patch
 create mode 100644 target/linux/generic/pending-5.4/510-ubifs-force-atomic-renames.patch

Comments

Richard Weinberger March 1, 2022, 7:37 p.m. UTC | #1
Rafał,

----- Ursprüngliche Mail -----
> Von: "Rafał Miłecki" <zajec5@gmail.com>
> An: "OpenWrt Development List" <openwrt-devel@lists.openwrt.org>
> CC: "Koen Vandeputte" <koen.vandeputte@ncentric.com>, "richard" <richard@nod.at>, "Rafał Miłecki" <rafal@milecki.pl>
> Gesendet: Dienstag, 1. März 2022 20:13:29
> Betreff: [PATCH] kernel: force atomic renames in ubifs

> From: Rafał Miłecki <rafal@milecki.pl>
> 
> This deals with user-spaces apps that don't handle all syncing
> correctly. It prevents user ending up with an empty file.
> 
> Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
> ---
> .../510-ubifs-force-atomic-renames.patch      | 46 +++++++++++++++++++
> .../510-ubifs-force-atomic-renames.patch      | 46 +++++++++++++++++++
> 2 files changed, 92 insertions(+)
> create mode 100644
> target/linux/generic/pending-5.10/510-ubifs-force-atomic-renames.patch
> create mode 100644
> target/linux/generic/pending-5.4/510-ubifs-force-atomic-renames.patch
> 
> diff --git
> a/target/linux/generic/pending-5.10/510-ubifs-force-atomic-renames.patch
> b/target/linux/generic/pending-5.10/510-ubifs-force-atomic-renames.patch
> new file mode 100644
> index 0000000000..80f5f1b910
> --- /dev/null
> +++ b/target/linux/generic/pending-5.10/510-ubifs-force-atomic-renames.patch
> @@ -0,0 +1,46 @@
> +From: Richard Weinberger <richard@nod.at>
> +Date: Mon, 28 Feb 2022 16:07:41 +0100
> +Subject: [PATCH] ubifs: force atomic renames
> +MIME-Version: 1.0
> +Content-Type: text/plain; charset=UTF-8
> +Content-Transfer-Encoding: 8bit
> +
> +Before actual rename make sure that the old inode data has been flash
> +written. This is similar to what other filesystems do and workarounds
> +bugs in some user-space apps.
> +
> +With this change updating file using tmpfile & rename() will never
> +result in losing all content e.g. on power cut.

Please slow down a bit. :-)
The commit message is not written by me and also not entirely correct.

The patch is not about making rename atomic. rename is already atomic
on UBIFS.
It is about syncing in flight pages when a file is overwritten by rename.

While I plan to upstream this change it still needs more testing.
I'm also not sure about the overhead it causes. Flushing the write buffers
can cause more garbage collection and may trigger write amplification.

Thanks,
//richard
Rafał Miłecki Nov. 27, 2023, 6:28 a.m. UTC | #2
Hi Richard,

On 1.03.2022 20:37, Richard Weinberger wrote:
> ----- Ursprüngliche Mail -----
>> Von: "Rafał Miłecki" <zajec5@gmail.com>
>> An: "OpenWrt Development List" <openwrt-devel@lists.openwrt.org>
>> CC: "Koen Vandeputte" <koen.vandeputte@ncentric.com>, "richard" <richard@nod.at>, "Rafał Miłecki" <rafal@milecki.pl>
>> Gesendet: Dienstag, 1. März 2022 20:13:29
>> Betreff: [PATCH] kernel: force atomic renames in ubifs
> 
>> From: Rafał Miłecki <rafal@milecki.pl>
>>
>> This deals with user-spaces apps that don't handle all syncing
>> correctly. It prevents user ending up with an empty file.
>>
>> Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
>> ---
>> .../510-ubifs-force-atomic-renames.patch      | 46 +++++++++++++++++++
>> .../510-ubifs-force-atomic-renames.patch      | 46 +++++++++++++++++++
>> 2 files changed, 92 insertions(+)
>> create mode 100644
>> target/linux/generic/pending-5.10/510-ubifs-force-atomic-renames.patch
>> create mode 100644
>> target/linux/generic/pending-5.4/510-ubifs-force-atomic-renames.patch
>>
>> diff --git
>> a/target/linux/generic/pending-5.10/510-ubifs-force-atomic-renames.patch
>> b/target/linux/generic/pending-5.10/510-ubifs-force-atomic-renames.patch
>> new file mode 100644
>> index 0000000000..80f5f1b910
>> --- /dev/null
>> +++ b/target/linux/generic/pending-5.10/510-ubifs-force-atomic-renames.patch
>> @@ -0,0 +1,46 @@
>> +From: Richard Weinberger <richard@nod.at>
>> +Date: Mon, 28 Feb 2022 16:07:41 +0100
>> +Subject: [PATCH] ubifs: force atomic renames
>> +MIME-Version: 1.0
>> +Content-Type: text/plain; charset=UTF-8
>> +Content-Transfer-Encoding: 8bit
>> +
>> +Before actual rename make sure that the old inode data has been flash
>> +written. This is similar to what other filesystems do and workarounds
>> +bugs in some user-space apps.
>> +
>> +With this change updating file using tmpfile & rename() will never
>> +result in losing all content e.g. on power cut.
> 
> Please slow down a bit. :-)
> The commit message is not written by me and also not entirely correct.
> 
> The patch is not about making rename atomic. rename is already atomic
> on UBIFS.
> It is about syncing in flight pages when a file is overwritten by rename.
> 
> While I plan to upstream this change it still needs more testing.
> I'm also not sure about the overhead it causes. Flushing the write buffers
> can cause more garbage collection and may trigger write amplification.

I didn't end up pushing this change to OpenWrt since your e-mail. I use
it however in my project in production in thousands of devices. I'd very
much like to see a proper change upstream.

Could you take a look at it, please?
diff mbox series

Patch

diff --git a/target/linux/generic/pending-5.10/510-ubifs-force-atomic-renames.patch b/target/linux/generic/pending-5.10/510-ubifs-force-atomic-renames.patch
new file mode 100644
index 0000000000..80f5f1b910
--- /dev/null
+++ b/target/linux/generic/pending-5.10/510-ubifs-force-atomic-renames.patch
@@ -0,0 +1,46 @@ 
+From: Richard Weinberger <richard@nod.at>
+Date: Mon, 28 Feb 2022 16:07:41 +0100
+Subject: [PATCH] ubifs: force atomic renames
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Before actual rename make sure that the old inode data has been flash
+written. This is similar to what other filesystems do and workarounds
+bugs in some user-space apps.
+
+With this change updating file using tmpfile & rename() will never
+result in losing all content e.g. on power cut.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+---
+ fs/ubifs/dir.c | 18 ++++++++++++++----
+ 1 file changed, 14 insertions(+), 4 deletions(-)
+
+--- a/fs/ubifs/dir.c
++++ b/fs/ubifs/dir.c
+@@ -1287,10 +1287,20 @@ static int do_rename(struct inode *old_d
+ 			return err;
+ 	}
+ 
+-	if (unlink && is_dir) {
+-		err = ubifs_check_dir_empty(new_inode);
+-		if (err)
+-			return err;
++	if (unlink) {
++		if (is_dir) {
++			err = ubifs_check_dir_empty(new_inode);
++			if (err)
++				return err;
++		} else {
++			err = filemap_fdatawrite(old_inode->i_mapping);
++			if (err)
++				return err;
++
++			err = ubifs_sync_wbufs_by_inode(c, old_inode);
++			if (err)
++				return err;
++		}
+ 	}
+ 
+ 	err = fscrypt_setup_filename(old_dir, &old_dentry->d_name, 0, &old_nm);
diff --git a/target/linux/generic/pending-5.4/510-ubifs-force-atomic-renames.patch b/target/linux/generic/pending-5.4/510-ubifs-force-atomic-renames.patch
new file mode 100644
index 0000000000..30bc686854
--- /dev/null
+++ b/target/linux/generic/pending-5.4/510-ubifs-force-atomic-renames.patch
@@ -0,0 +1,46 @@ 
+From: Richard Weinberger <richard@nod.at>
+Date: Mon, 28 Feb 2022 16:07:41 +0100
+Subject: [PATCH] ubifs: force atomic renames
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Before actual rename make sure that the old inode data has been flash
+written. This is similar to what other filesystems do and workarounds
+bugs in some user-space apps.
+
+With this change updating file using tmpfile & rename() will never
+result in losing all content e.g. on power cut.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+---
+ fs/ubifs/dir.c | 18 ++++++++++++++----
+ 1 file changed, 14 insertions(+), 4 deletions(-)
+
+--- a/fs/ubifs/dir.c
++++ b/fs/ubifs/dir.c
+@@ -1295,10 +1295,20 @@ static int do_rename(struct inode *old_d
+ 			return err;
+ 	}
+ 
+-	if (unlink && is_dir) {
+-		err = ubifs_check_dir_empty(new_inode);
+-		if (err)
+-			return err;
++	if (unlink) {
++		if (is_dir) {
++			err = ubifs_check_dir_empty(new_inode);
++			if (err)
++				return err;
++		} else {
++			err = filemap_fdatawrite(old_inode->i_mapping);
++			if (err)
++				return err;
++
++			err = ubifs_sync_wbufs_by_inode(c, old_inode);
++			if (err)
++				return err;
++		}
+ 	}
+ 
+ 	err = fscrypt_setup_filename(old_dir, &old_dentry->d_name, 0, &old_nm);