diff mbox series

[v5,06/28] btrfs: disallow NODATACOW in HMZONED mode

Message ID 20191204081735.852438-7-naohiro.aota@wdc.com (mailing list archive)
State New, archived
Headers show
Series btrfs: zoned block device support | expand

Commit Message

Naohiro Aota Dec. 4, 2019, 8:17 a.m. UTC
NODATACOW implies overwriting the file data on a device, which is
impossible in sequential required zones. Disable NODATACOW globally with
mount option and per-file NODATACOW attribute by masking FS_NOCOW_FL.

Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
---
 fs/btrfs/hmzoned.c | 6 ++++++
 fs/btrfs/ioctl.c   | 3 +++
 2 files changed, 9 insertions(+)

Comments

Johannes Thumshirn Dec. 5, 2019, 7:58 a.m. UTC | #1
Looks good,
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
David Sterba Dec. 5, 2019, 3:31 p.m. UTC | #2
On Wed, Dec 04, 2019 at 05:17:13PM +0900, Naohiro Aota wrote:
> NODATACOW implies overwriting the file data on a device, which is
> impossible in sequential required zones. Disable NODATACOW globally with
> mount option and per-file NODATACOW attribute by masking FS_NOCOW_FL.
> 
> Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
> ---
>  fs/btrfs/hmzoned.c | 6 ++++++
>  fs/btrfs/ioctl.c   | 3 +++
>  2 files changed, 9 insertions(+)
> 
> diff --git a/fs/btrfs/hmzoned.c b/fs/btrfs/hmzoned.c
> index 1c015ed050fc..e890d2ab8cd9 100644
> --- a/fs/btrfs/hmzoned.c
> +++ b/fs/btrfs/hmzoned.c
> @@ -269,5 +269,11 @@ int btrfs_check_mountopts_hmzoned(struct btrfs_fs_info *info)
>  		return -EINVAL;
>  	}
>  
> +	if (btrfs_test_opt(info, NODATACOW)) {
> +		btrfs_err(info,
> +		  "cannot enable nodatacow with HMZONED mode");
> +		return -EINVAL;

That's maybe -EOPNOTSUPP, the error message explains what's wrong and we
can leave EINVAL for the really invalid arguments. I'll need to look if
this is consistent with the rest of error code returned from mount
though.
Naohiro Aota Dec. 6, 2019, 5:37 a.m. UTC | #3
On Thu, Dec 05, 2019 at 04:31:42PM +0100, David Sterba wrote:
>On Wed, Dec 04, 2019 at 05:17:13PM +0900, Naohiro Aota wrote:
>> NODATACOW implies overwriting the file data on a device, which is
>> impossible in sequential required zones. Disable NODATACOW globally with
>> mount option and per-file NODATACOW attribute by masking FS_NOCOW_FL.
>>
>> Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
>> ---
>>  fs/btrfs/hmzoned.c | 6 ++++++
>>  fs/btrfs/ioctl.c   | 3 +++
>>  2 files changed, 9 insertions(+)
>>
>> diff --git a/fs/btrfs/hmzoned.c b/fs/btrfs/hmzoned.c
>> index 1c015ed050fc..e890d2ab8cd9 100644
>> --- a/fs/btrfs/hmzoned.c
>> +++ b/fs/btrfs/hmzoned.c
>> @@ -269,5 +269,11 @@ int btrfs_check_mountopts_hmzoned(struct btrfs_fs_info *info)
>>  		return -EINVAL;
>>  	}
>>
>> +	if (btrfs_test_opt(info, NODATACOW)) {
>> +		btrfs_err(info,
>> +		  "cannot enable nodatacow with HMZONED mode");
>> +		return -EINVAL;
>
>That's maybe -EOPNOTSUPP, the error message explains what's wrong and we
>can leave EINVAL for the really invalid arguments. I'll need to look if
>this is consistent with the rest of error code returned from mount
>though.

I'm OK with using -EOPNOTSUPP here in btrfs.

Just for a reference, F2FS returns -EINVAL when it has "nodiscard" or
"mode=adaptive" mount options on zoned block device.
diff mbox series

Patch

diff --git a/fs/btrfs/hmzoned.c b/fs/btrfs/hmzoned.c
index 1c015ed050fc..e890d2ab8cd9 100644
--- a/fs/btrfs/hmzoned.c
+++ b/fs/btrfs/hmzoned.c
@@ -269,5 +269,11 @@  int btrfs_check_mountopts_hmzoned(struct btrfs_fs_info *info)
 		return -EINVAL;
 	}
 
+	if (btrfs_test_opt(info, NODATACOW)) {
+		btrfs_err(info,
+		  "cannot enable nodatacow with HMZONED mode");
+		return -EINVAL;
+	}
+
 	return 0;
 }
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index a1ee0b775e65..a67421eb8bd5 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -94,6 +94,9 @@  static int btrfs_clone(struct inode *src, struct inode *inode,
 static unsigned int btrfs_mask_fsflags_for_type(struct inode *inode,
 		unsigned int flags)
 {
+	if (btrfs_fs_incompat(btrfs_sb(inode->i_sb), HMZONED))
+		flags &= ~FS_NOCOW_FL;
+
 	if (S_ISDIR(inode->i_mode))
 		return flags;
 	else if (S_ISREG(inode->i_mode))