From 318ea885ca5a8466842b4808ac631473229bd970 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 26 Feb 2021 17:39:55 +0100
Subject: [PATCH 2/9] btrfs-util: add helper that abstracts "might be btrfs
 subvol?" check

Conflict:adapt context
Reference:https://github.com/systemd/systemd/commit/674b04ff1b6deab17f5d36c036c0275ba94e1ebc

Let#s not hardcode inode nr 256 everywhere, but abstract this check
slightly.

(cherry picked from commit 674b04ff1b6deab17f5d36c036c0275ba94e1ebc)
---
 src/basic/btrfs-util.c     |  6 +++---
 src/basic/btrfs-util.h     | 10 ++++++++++
 src/basic/rm-rf.c          |  2 +-
 src/import/export-tar.c    |  2 +-
 src/shared/machine-image.c |  3 +--
 5 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/src/basic/btrfs-util.c b/src/basic/btrfs-util.c
index 540a199..e55378e 100644
--- a/src/basic/btrfs-util.c
+++ b/src/basic/btrfs-util.c
@@ -94,7 +94,7 @@ int btrfs_is_subvol_fd(int fd) {
         if (fstat(fd, &st) < 0)
                 return -errno;
 
-        if (!S_ISDIR(st.st_mode) || st.st_ino != 256)
+        if (!btrfs_might_be_subvol(&st))
                 return 0;
 
         return btrfs_is_filesystem(fd);
@@ -172,7 +172,7 @@ int btrfs_subvol_set_read_only_fd(int fd, bool b) {
         if (fstat(fd, &st) < 0)
                 return -errno;
 
-        if (!S_ISDIR(st.st_mode) || st.st_ino != 256)
+        if (!btrfs_might_be_subvol(&st))
                 return -EINVAL;
 
         if (ioctl(fd, BTRFS_IOC_SUBVOL_GETFLAGS, &flags) < 0)
@@ -211,7 +211,7 @@ int btrfs_subvol_get_read_only_fd(int fd) {
         if (fstat(fd, &st) < 0)
                 return -errno;
 
-        if (!S_ISDIR(st.st_mode) || st.st_ino != 256)
+        if (!btrfs_might_be_subvol(&st))
                 return -EINVAL;
 
         if (ioctl(fd, BTRFS_IOC_SUBVOL_GETFLAGS, &flags) < 0)
diff --git a/src/basic/btrfs-util.h b/src/basic/btrfs-util.h
index b15667b..0acd125 100644
--- a/src/basic/btrfs-util.h
+++ b/src/basic/btrfs-util.h
@@ -119,3 +119,13 @@ int btrfs_qgroup_find_parents(int fd, uint64_t qgroupid, uint64_t **ret);
 
 int btrfs_qgroup_get_quota_fd(int fd, uint64_t qgroupid, BtrfsQuotaInfo *quota);
 int btrfs_qgroup_get_quota(const char *path, uint64_t qgroupid, BtrfsQuotaInfo *quota);
+
+static inline bool btrfs_might_be_subvol(const struct stat *st) {
+        if (!st)
+                return false;
+
+        /* Returns true if this 'struct stat' looks like it could refer to a btrfs subvolume. To make a final
+         * decision, needs to be combined with an fstatfs() check to see if this is actually btrfs. */
+
+        return S_ISDIR(st->st_mode) && st->st_ino == 256;
+}
diff --git a/src/basic/rm-rf.c b/src/basic/rm-rf.c
index 03b41f3..26b943e 100644
--- a/src/basic/rm-rf.c
+++ b/src/basic/rm-rf.c
@@ -149,7 +149,7 @@ int rm_rf_children(int fd, RemoveFlags flags, struct stat *root_dev) {
                         if (r > 0)
                                 continue;
 
-                        if ((flags & REMOVE_SUBVOLUME) && st.st_ino == 256) {
+                        if ((flags & REMOVE_SUBVOLUME) && btrfs_might_be_subvol(&st)) {
 
                                 /* This could be a subvolume, try to remove it */
 
diff --git a/src/import/export-tar.c b/src/import/export-tar.c
index ed54676..aa5c717 100644
--- a/src/import/export-tar.c
+++ b/src/import/export-tar.c
@@ -284,7 +284,7 @@ int tar_export_start(TarExport *e, const char *path, int fd, ImportCompressType
 
         e->quota_referenced = (uint64_t) -1;
 
-        if (e->st.st_ino == 256) { /* might be a btrfs subvolume? */
+        if (btrfs_might_be_subvol(&e->st)) {
                 BtrfsQuotaInfo q;
 
                 r = btrfs_subvol_get_subtree_quota_fd(sfd, 0, &q);
diff --git a/src/shared/machine-image.c b/src/shared/machine-image.c
index 7007374..07bb80c 100644
--- a/src/shared/machine-image.c
+++ b/src/shared/machine-image.c
@@ -249,8 +249,7 @@ static int image_make(
                 if (fd < 0)
                         return -errno;
 
-                /* btrfs subvolumes have inode 256 */
-                if (st->st_ino == 256) {
+                if (btrfs_might_be_subvol(st)) {
 
                         r = btrfs_is_filesystem(fd);
                         if (r < 0)
-- 
2.23.0

