#5 add user fallbacks
Merged 8 months ago by dcavalca. Opened 8 months ago by sweettea.
rpms/ sweettea/btrfs-progs c9s-sig-hyperscale  into  c9s-sig-hyperscale

add user fallbacks
Sweet Tea Dorminy • 8 months ago  
@@ -0,0 +1,92 @@ 

+ From 6aae7985eb8ecb6faecb20376500f1026960a801 Mon Sep 17 00:00:00 2001

+ From: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>

+ Date: Mon, 4 Mar 2024 12:20:19 -0500

+ Subject: [PATCH] fall back to user ioctl for ino path lookup

+ 

+ ---

+  cmds/receive.c        |  2 +-

+  cmds/subvolume-list.c | 48 +++++++++++++++++++++++++++++++++++++++++++

+  2 files changed, 49 insertions(+), 1 deletion(-)

+ 

+ diff --git a/cmds/receive.c b/cmds/receive.c

+ index e4430b07..051eca6a 100644

+ --- a/cmds/receive.c

+ +++ b/cmds/receive.c

+ @@ -1285,7 +1285,7 @@ static int process_encoded_write(const char *path, const void *data, u64 offset,

+  		if (ret >= 0)

+  			return 0;

+  		/* Fall back for these errors, fail hard for anything else. */

+ -		if (errno != ENOSPC && errno != ENOTTY && errno != EINVAL) {

+ +		if (errno != ENOSPC && errno != ENOTTY && errno != EINVAL && errno != EPERM) {

+  			ret = -errno;

+  			error("encoded_write: writing to %s failed: %m", path);

+  			return ret;

+ diff --git a/cmds/subvolume-list.c b/cmds/subvolume-list.c

+ index 5a91f41d..c3bc7b70 100644

+ --- a/cmds/subvolume-list.c

+ +++ b/cmds/subvolume-list.c

+ @@ -759,6 +759,49 @@ static int resolve_root(struct rb_root *rl, struct root_info *ri,

+  	return 0;

+  }

+  

+ +/*

+ + * as user, for a single root_info, ask the kernel to give us a path name

+ + * inside it's ref_root for the dir_id where it lives.

+ + *

+ + * This fills in root_info->path with the path to the directory and and

+ + * appends this root's name.

+ + */

+ +static int lookup_ino_path_user(int fd, struct root_info *ri)

+ +{

+ +	struct btrfs_ioctl_ino_lookup_user_args args;

+ +	int ret;

+ +

+ +	if (ri->path)

+ +		return 0;

+ +

+ +	if (!ri->ref_tree)

+ +		return -ENOENT;

+ +

+ +	memset(&args, 0, sizeof(args));

+ +	args.treeid = ri->ref_tree;

+ +	args.dirid = ri->dir_id;

+ +

+ +	ret = ioctl(fd, BTRFS_IOC_INO_LOOKUP_USER, &args);

+ +	if (ret < 0) {

+ +		if (errno == ENOENT) {

+ +			ri->ref_tree = 0;

+ +			return -ENOENT;

+ +		}

+ +		error("failed to lookup path for root %llu: %m", ri->ref_tree);

+ +		return ret;

+ +	}

+ +

+ +	ri->path = malloc(strlen(args.name) + strlen(args.path) + 1);

+ +	if (!ri->path) {

+ +		error_msg(ERROR_MSG_MEMORY, NULL);

+ +		exit(1);

+ +	}

+ +

+ +	strcpy(ri->path, args.path);

+ +	strcat(ri->path, args.name);

+ +	return 0;

+ +}

+ +

+  /*

+   * for a single root_info, ask the kernel to give us a path name

+   * inside it's ref_root for the dir_id where it lives.

+ @@ -783,6 +826,11 @@ static int lookup_ino_path(int fd, struct root_info *ri)

+  

+  	ret = ioctl(fd, BTRFS_IOC_INO_LOOKUP, &args);

+  	if (ret < 0) {

+ +		if (errno == EPERM) {

+ +			/* Let's try again with the user ioctl */

+ +			return lookup_ino_path_user(fd, ri);

+ +		}

+ +

+  		if (errno == ENOENT) {

+  			ri->ref_tree = 0;

+  			return -ENOENT;

+ -- 

+ 2.44.0

+ 

file modified
+7 -1
@@ -3,7 +3,7 @@ 

  

  Name:           btrfs-progs

  Version:        6.7

- Release:        1.1%{?dist}

+ Release:        1.2%{?dist}

  Summary:        Userspace programs for btrfs

  

  License:        GPL-2.0-only
@@ -19,6 +19,9 @@ 

  # Patches not for upstream (1000-1400)

  ## Disable RAID56 modes

  Patch1001:      1001-balance-mkfs-Disable-raid56-modes.patch

+ %if 0%{?facebook}

+ Patch1002:      1002-fall-back-to-user-ioctl.patch

+ %endif

  

  BuildRequires:  gnupg2

  BuildRequires:  gcc, autoconf, automake, make
@@ -156,6 +159,9 @@ 

  %{python3_sitearch}/btrfsutil-*.egg-info/

  

  %changelog

+ * Mon Mar 4 2024 Sweet Tea Dorminy <sweettea@dorminy.me> - 6.7-1.2

+ - Add a facebook patch to have ino path resolution have a fallback.

+ 

  * Mon Jan 22 2024 Neal Gompa <ngompa@centosproject.org> - 6.7-1.1

  - Adapt for CentOS Hyperscale

  

To deal with a couple of user namespace permission issues, we would like to allow the btrfs command to fall back to user ino path lookup if root ino path lookup fails, and we would like to fall back to normal writes if encoded writes fail. This change adds a patch which does so.

What makes this patch not appropriate for upstreaming?

I believe upstream should always switch to the user ioctl, and should require a command line flag to fall back to unprivileged receive since it's less efficient. But this is the casual, quick version to unblock some things moving to user privileges.

rebased onto e02d455

8 months ago

Pull-Request has been merged by dcavalca

8 months ago

For future reference: I talked to Sweet Tea out of band and we decided to gate this to the FB build for now, as it's just a temporary stopgap until a proper solution is implemented upstream.