From 2159055ede95b410efe7a0925a499df1d8ee23b2 Mon Sep 17 00:00:00 2001
From: Giuseppe Scrivano <gscrivan@redhat.com>
Date: Fri, 31 Jan 2020 13:46:07 +0100
Subject: [PATCH] main: lookup skip ino if there is no origin
if there is no origin xattr specified, do not overwrite the ino
number.
Closes: https://github.com/containers/fuse-overlayfs/issues/177
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
---
main.c | 48 ++++++++++++++++++++++++++++++++++++++----------
1 file changed, 38 insertions(+), 10 deletions(-)
diff --git a/main.c b/main.c
index b1bdfa4..ba12faa 100644
--- a/main.c
+++ b/main.c
@@ -1,7 +1,7 @@
/* fuse-overlayfs: Overlay Filesystem in Userspace
Copyright (C) 2018 Giuseppe Scrivano <giuseppe@scrivano.org>
- Copyright (C) 2018-2019 Red Hat Inc.
+ Copyright (C) 2018-2020 Red Hat Inc.
Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
This program is free software: you can redistribute it and/or modify
@@ -456,6 +456,22 @@ has_prefix (const char *str, const char *pref)
return false;
}
+static int
+set_fd_origin (int fd, const char *origin)
+{
+ cleanup_close int opq_whiteout_fd = -1;
+ size_t len = strlen (origin) + 1;
+ int ret;
+
+ ret = fsetxattr (fd, ORIGIN_XATTR, origin, len, 0);
+ if (ret < 0)
+ {
+ if (errno == ENOTSUP)
+ return 0;
+ }
+ return ret;
+}
+
static int
set_fd_opaque (int fd)
{
@@ -1131,6 +1147,7 @@ make_ovl_node (struct ovl_data *lo, const char *path, struct ovl_layer *layer, c
mode_t mode = 0;
char *new_name;
struct ovl_node *ret_xchg;
+ bool has_origin = true;
cleanup_node_init struct ovl_node *ret = NULL;
ret = calloc (1, sizeof (*ret));
@@ -1211,10 +1228,13 @@ make_ovl_node (struct ovl_data *lo, const char *path, struct ovl_layer *layer, c
{
if (it->ds->statat (it, npath, &st, AT_SYMLINK_NOFOLLOW, STATX_TYPE|STATX_MODE|STATX_INO) == 0)
{
- ret->tmp_ino = st.st_ino;
- ret->tmp_dev = st.st_dev;
- if (mode == 0)
- mode = st.st_mode;
+ if (has_origin)
+ {
+ ret->tmp_ino = st.st_ino;
+ ret->tmp_dev = st.st_dev;
+ if (mode == 0)
+ mode = st.st_mode;
+ }
ret->last_layer = it;
}
goto no_fd;
@@ -1223,10 +1243,13 @@ make_ovl_node (struct ovl_data *lo, const char *path, struct ovl_layer *layer, c
/* It is an open FD, stat the file and read the origin xattrs. */
if (it->ds->fstat (it, fd, npath, STATX_TYPE|STATX_MODE|STATX_INO, &st) == 0)
{
- ret->tmp_ino = st.st_ino;
- ret->tmp_dev = st.st_dev;
- if (mode == 0)
- mode = st.st_mode;
+ if (has_origin)
+ {
+ ret->tmp_ino = st.st_ino;
+ ret->tmp_dev = st.st_dev;
+ if (mode == 0)
+ mode = st.st_mode;
+ }
ret->last_layer = it;
}
@@ -1270,7 +1293,9 @@ make_ovl_node (struct ovl_data *lo, const char *path, struct ovl_layer *layer, c
/* If an origin is specified, use it for the next layer lookup. */
s = safe_read_xattr (&origin, fd, ORIGIN_XATTR, PATH_MAX);
- if (s > 0)
+ if (s <= 0)
+ has_origin = false;
+ else
{
free (npath);
npath = origin;
@@ -2656,6 +2681,9 @@ copyup (struct ovl_data *lo, struct ovl_node *node)
if (ret < 0)
goto exit;
+ if (set_fd_origin (dfd, node->path) < 0)
+ goto exit;
+
/* Finally, move the file to its destination. */
ret = renameat (lo->workdir_fd, wd_tmp_file_name, get_upper_layer (lo)->fd, node->path);
if (ret < 0)
--
2.24.1