diff --git a/debian/changelog b/debian/changelog index 4315a596b..1870577ed 100644 --- a/debian/changelog +++ b/debian/changelog @@ -53,6 +53,7 @@ linux (4.1.6-1) UNRELEASED; urgency=medium * [i386] udeb: Make gpio_keys_polled and leds-gpio optional in input-modules as they are not built for the 686-pae flavour (fixes FTBFS) * perf: Fix AUX buffer refcounting + * ovl: Revert changes in 4.1.5-1 due to regression (Reopens: #786925) -- Aurelien Jarno Tue, 18 Aug 2015 11:35:05 +0200 diff --git a/debian/patches/bugfix/all/-ovl-don-t-traverse-automount-points.patch b/debian/patches/bugfix/all/-ovl-don-t-traverse-automount-points.patch deleted file mode 100644 index 84a92514f..000000000 --- a/debian/patches/bugfix/all/-ovl-don-t-traverse-automount-points.patch +++ /dev/null @@ -1,50 +0,0 @@ -From: Miklos Szeredi -Date: Mon, 22 Jun 2015 13:53:48 +0200 -Subject: ovl: don't traverse automount points -Origin: https://git.kernel.org/linus/a6f15d9a756571babbb2b2cd4fdd1b64a5de232b -Bug-Debian: https://bugs.debian.org/786925 - -NFS and other distributed filesystems may place automount points in the -tree. Previoulsy overlayfs refused to mount such filesystems types (based -on the existence of the .d_automount callback), even if the actual export -didn't have any automount points. - -It cannot be determined in advance whether the filesystem has automount -points or not. The solution is to allow fs with .d_automount but refuse to -traverse any automount points encountered. - -Signed-off-by: Miklos Szeredi ---- - fs/overlayfs/super.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c -index bf8537c..de9d2ee 100644 ---- a/fs/overlayfs/super.c -+++ b/fs/overlayfs/super.c -@@ -303,6 +303,10 @@ static inline struct dentry *ovl_lookup_real(struct dentry *dir, - } else if (!dentry->d_inode) { - dput(dentry); - dentry = NULL; -+ } else if (dentry->d_flags & DCACHE_MANAGED_DENTRY) { -+ dput(dentry); -+ /* Don't support traversing automounts */ -+ dentry = ERR_PTR(-EREMOTE); - } - return dentry; - } -@@ -700,12 +704,12 @@ static bool ovl_is_allowed_fs_type(struct dentry *root) - - /* - * We don't support: -- * - automount filesystems -+ * - autofs - * - filesystems with revalidate (FIXME for lower layer) - * - filesystems with case insensitive names - */ - if (dop && -- (dop->d_manage || dop->d_automount || -+ (dop->d_manage || - dop->d_revalidate || dop->d_weak_revalidate || - dop->d_compare || dop->d_hash)) { - return false; diff --git a/debian/patches/bugfix/all/fix-a-braino-in-ovl_d_select_inode.patch b/debian/patches/bugfix/all/fix-a-braino-in-ovl_d_select_inode.patch deleted file mode 100644 index 903118e94..000000000 --- a/debian/patches/bugfix/all/fix-a-braino-in-ovl_d_select_inode.patch +++ /dev/null @@ -1,28 +0,0 @@ -From: Al Viro -Date: Sun, 12 Jul 2015 10:39:45 -0400 -Subject: fix a braino in ovl_d_select_inode() -Origin: https://git.kernel.org/linus/9391dd00d13c853ab4f2a85435288ae2202e0e43 -Bug-Debian: https://bugs.debian.org/786925 - -when opening a directory we want the overlayfs inode, not one from -the topmost layer. - -Reported-By: Andrey Jr. Melnikov -Tested-By: Andrey Jr. Melnikov -Signed-off-by: Al Viro ---- - fs/overlayfs/inode.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/fs/overlayfs/inode.c -+++ b/fs/overlayfs/inode.c -@@ -344,6 +344,9 @@ static int ovl_dentry_open(struct dentry - enum ovl_path_type type; - bool want_write = false; - -+ if (d_is_dir(dentry)) -+ return d_backing_inode(dentry); -+ - type = ovl_path_real(dentry, &realpath); - if (ovl_open_need_copy_up(file->f_flags, type, realpath.dentry)) { - want_write = true; diff --git a/debian/patches/bugfix/all/ovl-allow-distributed-fs-as-lower-layer.patch b/debian/patches/bugfix/all/ovl-allow-distributed-fs-as-lower-layer.patch deleted file mode 100644 index 66976e292..000000000 --- a/debian/patches/bugfix/all/ovl-allow-distributed-fs-as-lower-layer.patch +++ /dev/null @@ -1,227 +0,0 @@ -From: Miklos Szeredi -Date: Mon, 22 Jun 2015 13:53:48 +0200 -Subject: ovl: allow distributed fs as lower layer -Origin: https://git.kernel.org/linus/7c03b5d45b8eebf0111125053d8fe887cc262ba6 -Bug-Debian: https://bugs.debian.org/786925 - -Allow filesystems with .d_revalidate as lower layer(s), but not as upper -layer. - -For local filesystems the rule was that modifications on the layers -directly while being part of the overlay results in undefined behavior. - -This can easily be extended to distributed filesystems: we assume the tree -used as lower layer is static, which means ->d_revalidate() should always -return "1". If that is not the case, return -ESTALE, don't try to work -around the modification. - -Signed-off-by: Miklos Szeredi ---- - fs/overlayfs/super.c | 113 +++++++++++++++++++++++++++++++++++++++------------ - 1 file changed, 88 insertions(+), 25 deletions(-) - -diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c -index de9d2ee..8a08c58 100644 ---- a/fs/overlayfs/super.c -+++ b/fs/overlayfs/super.c -@@ -273,10 +273,57 @@ static void ovl_dentry_release(struct dentry *dentry) - } - } - -+static int ovl_dentry_revalidate(struct dentry *dentry, unsigned int flags) -+{ -+ struct ovl_entry *oe = dentry->d_fsdata; -+ unsigned int i; -+ int ret = 1; -+ -+ for (i = 0; i < oe->numlower; i++) { -+ struct dentry *d = oe->lowerstack[i].dentry; -+ -+ if (d->d_flags & DCACHE_OP_REVALIDATE) { -+ ret = d->d_op->d_revalidate(d, flags); -+ if (ret < 0) -+ return ret; -+ if (!ret) { -+ if (!(flags & LOOKUP_RCU)) -+ d_invalidate(d); -+ return -ESTALE; -+ } -+ } -+ } -+ return 1; -+} -+ -+static int ovl_dentry_weak_revalidate(struct dentry *dentry, unsigned int flags) -+{ -+ struct ovl_entry *oe = dentry->d_fsdata; -+ unsigned int i; -+ int ret = 1; -+ -+ for (i = 0; i < oe->numlower; i++) { -+ struct dentry *d = oe->lowerstack[i].dentry; -+ -+ if (d->d_flags & DCACHE_OP_WEAK_REVALIDATE) { -+ ret = d->d_op->d_weak_revalidate(d, flags); -+ if (ret <= 0) -+ break; -+ } -+ } -+ return ret; -+} -+ - static const struct dentry_operations ovl_dentry_operations = { - .d_release = ovl_dentry_release, - }; - -+static const struct dentry_operations ovl_reval_dentry_operations = { -+ .d_release = ovl_dentry_release, -+ .d_revalidate = ovl_dentry_revalidate, -+ .d_weak_revalidate = ovl_dentry_weak_revalidate, -+}; -+ - static struct ovl_entry *ovl_alloc_entry(unsigned int numlower) - { - size_t size = offsetof(struct ovl_entry, lowerstack[numlower]); -@@ -288,6 +335,20 @@ static struct ovl_entry *ovl_alloc_entry(unsigned int numlower) - return oe; - } - -+static bool ovl_dentry_remote(struct dentry *dentry) -+{ -+ return dentry->d_flags & -+ (DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE); -+} -+ -+static bool ovl_dentry_weird(struct dentry *dentry) -+{ -+ return dentry->d_flags & (DCACHE_NEED_AUTOMOUNT | -+ DCACHE_MANAGE_TRANSIT | -+ DCACHE_OP_HASH | -+ DCACHE_OP_COMPARE); -+} -+ - static inline struct dentry *ovl_lookup_real(struct dentry *dir, - struct qstr *name) - { -@@ -303,9 +364,9 @@ static inline struct dentry *ovl_lookup_real(struct dentry *dir, - } else if (!dentry->d_inode) { - dput(dentry); - dentry = NULL; -- } else if (dentry->d_flags & DCACHE_MANAGED_DENTRY) { -+ } else if (ovl_dentry_weird(dentry)) { - dput(dentry); -- /* Don't support traversing automounts */ -+ /* Don't support traversing automounts and other weirdness */ - dentry = ERR_PTR(-EREMOTE); - } - return dentry; -@@ -354,6 +415,11 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, - goto out; - - if (this) { -+ if (unlikely(ovl_dentry_remote(this))) { -+ dput(this); -+ err = -EREMOTE; -+ goto out; -+ } - if (ovl_is_whiteout(this)) { - dput(this); - this = NULL; -@@ -698,25 +764,6 @@ static void ovl_unescape(char *s) - } - } - --static bool ovl_is_allowed_fs_type(struct dentry *root) --{ -- const struct dentry_operations *dop = root->d_op; -- -- /* -- * We don't support: -- * - autofs -- * - filesystems with revalidate (FIXME for lower layer) -- * - filesystems with case insensitive names -- */ -- if (dop && -- (dop->d_manage || -- dop->d_revalidate || dop->d_weak_revalidate || -- dop->d_compare || dop->d_hash)) { -- return false; -- } -- return true; --} -- - static int ovl_mount_dir_noesc(const char *name, struct path *path) - { - int err = -EINVAL; -@@ -731,7 +778,7 @@ static int ovl_mount_dir_noesc(const char *name, struct path *path) - goto out; - } - err = -EINVAL; -- if (!ovl_is_allowed_fs_type(path->dentry)) { -+ if (ovl_dentry_weird(path->dentry)) { - pr_err("overlayfs: filesystem on '%s' not supported\n", name); - goto out_put; - } -@@ -755,13 +802,21 @@ static int ovl_mount_dir(const char *name, struct path *path) - if (tmp) { - ovl_unescape(tmp); - err = ovl_mount_dir_noesc(tmp, path); -+ -+ if (!err) -+ if (ovl_dentry_remote(path->dentry)) { -+ pr_err("overlayfs: filesystem on '%s' not supported as upperdir\n", -+ tmp); -+ path_put(path); -+ err = -EINVAL; -+ } - kfree(tmp); - } - return err; - } - - static int ovl_lower_dir(const char *name, struct path *path, long *namelen, -- int *stack_depth) -+ int *stack_depth, bool *remote) - { - int err; - struct kstatfs statfs; -@@ -778,6 +833,9 @@ static int ovl_lower_dir(const char *name, struct path *path, long *namelen, - *namelen = max(*namelen, statfs.f_namelen); - *stack_depth = max(*stack_depth, path->mnt->mnt_sb->s_stack_depth); - -+ if (ovl_dentry_remote(path->dentry)) -+ *remote = true; -+ - return 0; - - out_put: -@@ -831,6 +889,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) - unsigned int numlower; - unsigned int stacklen = 0; - unsigned int i; -+ bool remote = false; - int err; - - err = -ENOMEM; -@@ -904,7 +963,8 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) - lower = lowertmp; - for (numlower = 0; numlower < stacklen; numlower++) { - err = ovl_lower_dir(lower, &stack[numlower], -- &ufs->lower_namelen, &sb->s_stack_depth); -+ &ufs->lower_namelen, &sb->s_stack_depth, -+ &remote); - if (err) - goto out_put_lowerpath; - -@@ -962,7 +1022,10 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) - if (!ufs->upper_mnt) - sb->s_flags |= MS_RDONLY; - -- sb->s_d_op = &ovl_dentry_operations; -+ if (remote) -+ sb->s_d_op = &ovl_reval_dentry_operations; -+ else -+ sb->s_d_op = &ovl_dentry_operations; - - err = -ENOMEM; - oe = ovl_alloc_entry(numlower); diff --git a/debian/patches/series b/debian/patches/series index e54bbb606..eea0a6b99 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -87,8 +87,5 @@ features/all/grsecurity/grsecurity-kconfig.patch #features/all/grsecurity/grsecurity-kbuild.patch features/all/grsecurity/grkernsec_perf_harden.patch bugfix/all/virtio-net-drop-netif_f_fraglist.patch -bugfix/all/-ovl-don-t-traverse-automount-points.patch -bugfix/all/ovl-allow-distributed-fs-as-lower-layer.patch -bugfix/all/fix-a-braino-in-ovl_d_select_inode.patch bugfix/all/perf-fix-aux-buffer-refcounting.patch bugfix/all/perf-fix-double-free-of-the-aux-buffer.patch