[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#850884: marked as done (overlayfs does not implement inotify interfaces correctly)



Your message dated Thu, 13 May 2021 22:38:55 +0200
with message-id <YJ2OX7U/JtRQWQjo@eldamar.lan>
and subject line Re: Bug#850884: overlayfs does not implement inotify interfaces correctly
has caused the Debian Bug report #850884,
regarding overlayfs does not implement inotify interfaces correctly
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
850884: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=850884
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: linux-source-4.8
Severity: important
Tags: patch

When using tail on the liveCD some updates are not reported. This seems to be
triggered by tail using inotify to identify modified files. Overlayfs does not
appear to be implementing inotify quite the way you might hope reporting only
against the underlying filesystems.

^^ This is the description of the original bug filed 2011-10-26 by
Andy Whitcroft. (https://bugs.launchpad.net/ubuntu/+source/linux/+bug/882147)

It still applies and the bug is still present and still renders live isos
unusable to a degree. One could say it's a "non-feature" but i would still
call it bug. Unfortunately debian-live-isos are bitten by this too.

The applied patch is the basicly the patch in the bugreport and applies to
kernel 4.8 - and solve the problem with live isos.

Cheers Alf 

-- System Information:
Debian Release: stretch/sid
  APT prefers buildd-unstable
  APT policy: (500, 'buildd-unstable'), (500, 'unstable'), (500, 'testing'), (500, 'stable'), (1, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 4.9.2-towo.1-siduction-amd64 (SMP w/8 CPU cores; PREEMPT)
Locale: LANG=de_DE.utf8, LC_CTYPE=de_DE.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
diff --git a/fs/notify/inotify/Kconfig b/fs/notify/inotify/Kconfig
index b981fc0..1ccd92e 100644
--- a/fs/notify/inotify/Kconfig
+++ b/fs/notify/inotify/Kconfig
@@ -15,3 +15,12 @@ config INOTIFY_USER
 	  For more information, see <file:Documentation/filesystems/inotify.txt>
 
 	  If unsure, say Y.
+
+config INOTIFY_STACKFS
+	bool "Inotify support for stackable filesystem"
+	select INOTIFY_USER
+	default y
+	---help---
+	  Say Y here to enable inotify support for stackable filesystem.
+
+	  If unsure, say N.
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index 60f954a..3daff50 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -24,6 +24,7 @@
 
 #include <linux/file.h>
 #include <linux/fs.h> /* struct inode */
+#include <linux/mount.h>
 #include <linux/fsnotify_backend.h>
 #include <linux/idr.h>
 #include <linux/init.h> /* fs_initcall */
@@ -86,6 +86,94 @@
 };
 #endif /* CONFIG_SYSCTL */
 
+#ifdef CONFIG_INOTIFY_STACKFS
+
+static DEFINE_RWLOCK(inotify_fs_lock);
+static LIST_HEAD(inotify_fs_list);
+
+static inline struct file_system_type* peek_fs_type(struct path *path)
+{
+	return path->mnt->mnt_sb->s_type;
+}
+
+static struct inotify_stackfs* inotify_get_stackfs(struct path *path)
+{
+	struct file_system_type *fs;
+	struct inotify_stackfs *fse, *ret = NULL;
+
+	fs = peek_fs_type(path);
+
+	read_lock(&inotify_fs_lock);
+	list_for_each_entry(fse, &inotify_fs_list, list) {
+		if (fse->fs_type == fs) {
+			ret = fse;
+			break;
+		}
+	}
+	read_unlock(&inotify_fs_lock);
+
+	return ret;
+}
+
+static inline void inotify_put_stackfs(struct inotify_stackfs *fs)
+{
+}
+
+int inotify_register_stackfs(struct inotify_stackfs *fs)
+{
+	int ret = 0;
+	struct inotify_stackfs *fse;
+
+	BUG_ON(IS_ERR_OR_NULL(fs->fs_type));
+	BUG_ON(IS_ERR_OR_NULL(fs->func));
+
+	INIT_LIST_HEAD(&fs->list);
+
+	write_lock(&inotify_fs_lock);
+	list_for_each_entry(fse, &inotify_fs_list, list) {
+		if (fse->fs_type == fs->fs_type) {
+			write_unlock(&inotify_fs_lock);
+			ret = -EBUSY;
+			goto out;
+		}
+	}
+	list_add_tail(&fs->list, &inotify_fs_list);
+	write_unlock(&inotify_fs_lock);
+
+out:
+	return ret;
+}
+EXPORT_SYMBOL_GPL(inotify_register_stackfs);
+
+void inotify_unregister_stackfs(struct inotify_stackfs *fs)
+{
+	struct inotify_stackfs *fse, *n;
+
+	write_lock(&inotify_fs_lock);
+	list_for_each_entry_safe(fse, n, &inotify_fs_list, list) {
+		if (fse == fs) {
+			list_del(&fse->list);
+			break;
+		}
+	}
+	write_unlock(&inotify_fs_lock);
+}
+EXPORT_SYMBOL_GPL(inotify_unregister_stackfs);
+
+#else
+
+static inline struct inotify_stackfs* inotify_get_stackfs(struct path *path)
+{
+	return NULL;
+}
+
+static inline void inotify_put_stackfs(struct inotify_stackfs *fs)
+{
+}
+
+#endif /* CONFIG_INOTIFY_STACKFS */
+
+
 static inline __u32 inotify_arg_to_mask(u32 arg)
 {
 	__u32 mask;
@@ -329,7 +417,7 @@
 /*
  * find_inode - resolve a user-given path to a specific inode
  */
-static int inotify_find_inode(const char __user *dirname, struct path *path, unsigned flags)
+static inline int __inotify_find_inode(const char __user *dirname, struct path *path, unsigned flags)
 {
 	int error;
 
@@ -343,6 +431,27 @@
 	return error;
 }
 
+static int inotify_find_inode(const char __user *dirname, struct path *path, unsigned flags)
+{
+	int ret;
+	struct path tpath;
+	struct inotify_stackfs *fse;
+
+	ret = __inotify_find_inode(dirname, &tpath, flags);
+	if (ret)
+		return ret;
+	fse = inotify_get_stackfs(&tpath);
+	if (fse == NULL) {
+		*path = tpath;
+		return 0;
+	}
+	ret = fse->func(path, &tpath);
+	inotify_put_stackfs(fse);
+	path_put(&tpath);
+
+	return ret;
+}
+
 static int inotify_add_to_idr(struct idr *idr, spinlock_t *idr_lock,
 			      struct inotify_inode_mark *i_mark)
 {
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 9473e79..4af5048 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -19,6 +19,7 @@
 #include <linux/sched.h>
 #include <linux/statfs.h>
 #include <linux/seq_file.h>
+#include <linux/inotify.h>
 #include <linux/posix_acl_xattr.h>
 #include "overlayfs.h"
 
@@ -1395,13 +1396,39 @@
 };
 MODULE_ALIAS_FS("overlay");
 
+static int ovl_inotify_path(struct path *dst, struct path *src)
+{
+	ovl_path_real(src->dentry, dst);
+
+	path_get(dst);
+
+	return 0;
+}
+
+static struct inotify_stackfs ovl_inotify = {
+	.fs_type	= &ovl_fs_type,
+	.func		= ovl_inotify_path,
+};
+
 static int __init ovl_init(void)
 {
-	return register_filesystem(&ovl_fs_type);
+	int ret;
+
+	ret = register_filesystem(&ovl_fs_type);
+	if (ret)
+		return ret;
+	ret = inotify_register_stackfs(&ovl_inotify);
+	if (ret) {
+		pr_err("overlayfs: hook inotify error\n");
+		unregister_filesystem(&ovl_fs_type);
+	}
+
+	return ret;
 }
 
 static void __exit ovl_exit(void)
 {
+	inotify_unregister_stackfs(&ovl_inotify);
 	unregister_filesystem(&ovl_fs_type);
 }
 
diff --git a/include/linux/inotify.h b/include/linux/inotify.h
index 23aede0..2c4d7a1 100644
--- a/include/linux/inotify.h
+++ b/include/linux/inotify.h
@@ -8,6 +8,8 @@
 
 #include <linux/sysctl.h>
 #include <uapi/linux/inotify.h>
+#include <linux/list.h>
+#include <linux/fs.h>
 
 extern struct ctl_table inotify_table[]; /* for sysctl */
 
@@ -19,4 +21,30 @@ extern struct ctl_table inotify_table[]; /* for sysctl */
 			  IN_DONT_FOLLOW | IN_EXCL_UNLINK | IN_MASK_ADD | \
 			  IN_ISDIR | IN_ONESHOT)
 
+typedef int (*inotify_path_proc)(struct path *dst, struct path *src);
+
+struct inotify_stackfs {
+	struct list_head	list;		/* entry in inotify_fs_list */
+	struct file_system_type	*fs_type;	/* registed file_system_type */	
+	inotify_path_proc	func;		/* registed callback function */
+};
+
+#ifdef CONFIG_INOTIFY_STACKFS
+
+extern int inotify_register_stackfs(struct inotify_stackfs *fs);
+extern void inotify_unregister_stackfs(struct inotify_stackfs *fs);
+
+#else
+
+static inline int inotify_register_stackfs(struct inotify_stackfs *fs)
+{
+	return 0;
+}
+
+static inline void inotify_unregister_stackfs(struct inotify_stackfs *fs)
+{
+}
+
+#endif	/* CONFIG_INOTIFY_STACKFS */
+
 #endif	/* _LINUX_INOTIFY_H */

--- End Message ---
--- Begin Message ---
Hi,

On Tue, Jan 10, 2017 at 09:58:36PM +0100, Alf Gaida wrote:
> Package: linux-source-4.8
> Severity: important
> Tags: patch
> 
> When using tail on the liveCD some updates are not reported. This seems to be
> triggered by tail using inotify to identify modified files. Overlayfs does not
> appear to be implementing inotify quite the way you might hope reporting only
> against the underlying filesystems.
> 
> ^^ This is the description of the original bug filed 2011-10-26 by
> Andy Whitcroft. (https://bugs.launchpad.net/ubuntu/+source/linux/+bug/882147)
> 
> It still applies and the bug is still present and still renders live isos
> unusable to a degree. One could say it's a "non-feature" but i would still
> call it bug. Unfortunately debian-live-isos are bitten by this too.
> 
> The applied patch is the basicly the patch in the bugreport and applies to
> kernel 4.8 - and solve the problem with live isos.

As Ben said, this would need to be handled upstream instead as we very
rearely will apply patches for features which do not exist upstream.
As such closing this downstream report.

Regards,
Salvatore

--- End Message ---

Reply to: