From 81c939f350fc71ff3d06ca7b80179716206e4a0b Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Wed, 11 Jul 2018 16:57:59 +0200 Subject: [PATCH] fuse-overlayfs: attempt to create mknod whiteout before attempting the .wh. fallback Signed-off-by: Giuseppe Scrivano --- main.c | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/main.c b/main.c index 16cb4da..19e7860 100644 --- a/main.c +++ b/main.c @@ -286,6 +286,23 @@ create_whiteout (struct ovl_data *lo, struct ovl_node *parent, const char *name) { char whiteout_path[PATH_MAX + 10]; int fd = -1; + static bool can_mknod = true; + + if (can_mknod) + { + int ret; + + sprintf (whiteout_path, "%s/%s", parent->path, name); + ret = mknodat (get_upper_layer (lo)->fd, whiteout_path, S_IFCHR|0700, makedev (0, 0)); + if (ret == 0) + return 0; + + if (errno != EPERM) + return -1; + + /* if it fails with EPERM then do not attempt mknod again. */ + can_mknod = false; + } sprintf (whiteout_path, "%s/.wh.%s", parent->path, name); fd = TEMP_FAILURE_RETRY (openat (get_upper_layer (lo)->fd, whiteout_path, O_CREAT|O_WRONLY, 0700)); @@ -1614,6 +1631,20 @@ do_rm (fuse_req_t req, fuse_ino_t parent, const char *name, bool dirp) return; } + key.name = (char *) name; + rm = hash_delete (pnode->children, &key); + if (rm) + { + ret = hide_node (lo, rm, true); + if (ret < 0) + { + fuse_reply_err (req, errno); + return; + } + + node_free (rm); + } + ret = create_whiteout (lo, pnode, name); if (ret < 0) { @@ -1621,16 +1652,6 @@ do_rm (fuse_req_t req, fuse_ino_t parent, const char *name, bool dirp) return; } - ret = 0; - - key.name = (char *) name; - rm = hash_delete (pnode->children, &key); - if (rm) - { - hide_node (lo, rm, true); - node_free (rm); - } - fuse_reply_err (req, ret); }