aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-04-28 11:29:56 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-05-07 11:56:32 -0400
commitd25895e8f1e5e29823d373096d8f3d271bf11821 (patch)
tree3332513bc52ace07120ddb1c8e500a16baff2cf8
parent322fd620a858fab9c1ea85a7cfebe3fc041d7126 (diff)
Revert "autofs: work around unhappy compat problem on x86-64"
commit fcbf94b9dedd2ce08e798a99aafc94fec8668161 upstream. This reverts commit a32744d4abae24572eff7269bc17895c41bd0085. While that commit was technically the right thing to do, and made the x86-64 compat mode work identically to native 32-bit mode (and thus fixing the problem with a 32-bit systemd install on a 64-bit kernel), it turns out that the automount binaries had workarounds for this compat problem. Now, the workarounds are disgusting: doing an "uname()" to find out the architecture of the kernel, and then comparing it for the 64-bit cases and fixing up the size of the read() in automount for those. And they were confused: it's not actually a generic 64-bit issue at all, it's very much tied to just x86-64, which has different alignment for an 'u64' in 64-bit mode than in 32-bit mode. But the end result is that fixing the compat layer actually breaks the case of a 32-bit automount on a x86-64 kernel. There are various approaches to fix this (including just doing a "strcmp()" on current->comm and comparing it to "automount"), but I think that I will do the one that teaches pipes about a special "packet mode", which will allow user space to not have to care too deeply about the padding at the end of the autofs packet. That change will make the compat workaround unnecessary, so let's revert it first, and get automount working again in compat mode. The packetized pipes will then fix autofs for systemd. Reported-and-requested-by: Michael Tokarev <mjt@tls.msk.ru> Cc: Ian Kent <raven@themaw.net> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--fs/autofs4/autofs_i.h1
-rw-r--r--fs/autofs4/dev-ioctl.c1
-rw-r--r--fs/autofs4/inode.c2
-rw-r--r--fs/autofs4/waitq.c20
4 files changed, 2 insertions, 22 deletions
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
index 10cc45aea22..475f9c597cb 100644
--- a/fs/autofs4/autofs_i.h
+++ b/fs/autofs4/autofs_i.h
@@ -120,7 +120,6 @@ struct autofs_sb_info {
120 int sub_version; 120 int sub_version;
121 int min_proto; 121 int min_proto;
122 int max_proto; 122 int max_proto;
123 int compat_daemon;
124 unsigned long exp_timeout; 123 unsigned long exp_timeout;
125 unsigned int type; 124 unsigned int type;
126 int reghost_enabled; 125 int reghost_enabled;
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c
index 56bac702ab0..509fe1eb66a 100644
--- a/fs/autofs4/dev-ioctl.c
+++ b/fs/autofs4/dev-ioctl.c
@@ -385,7 +385,6 @@ static int autofs_dev_ioctl_setpipefd(struct file *fp,
385 sbi->pipefd = pipefd; 385 sbi->pipefd = pipefd;
386 sbi->pipe = pipe; 386 sbi->pipe = pipe;
387 sbi->catatonic = 0; 387 sbi->catatonic = 0;
388 sbi->compat_daemon = is_compat_task();
389 } 388 }
390out: 389out:
391 mutex_unlock(&sbi->wq_mutex); 390 mutex_unlock(&sbi->wq_mutex);
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index eb1e45ce303..180fa2425e4 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -19,7 +19,6 @@
19#include <linux/parser.h> 19#include <linux/parser.h>
20#include <linux/bitops.h> 20#include <linux/bitops.h>
21#include <linux/magic.h> 21#include <linux/magic.h>
22#include <linux/compat.h>
23#include "autofs_i.h" 22#include "autofs_i.h"
24#include <linux/module.h> 23#include <linux/module.h>
25 24
@@ -225,7 +224,6 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
225 set_autofs_type_indirect(&sbi->type); 224 set_autofs_type_indirect(&sbi->type);
226 sbi->min_proto = 0; 225 sbi->min_proto = 0;
227 sbi->max_proto = 0; 226 sbi->max_proto = 0;
228 sbi->compat_daemon = is_compat_task();
229 mutex_init(&sbi->wq_mutex); 227 mutex_init(&sbi->wq_mutex);
230 spin_lock_init(&sbi->fs_lock); 228 spin_lock_init(&sbi->fs_lock);
231 sbi->queues = NULL; 229 sbi->queues = NULL;
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
index fbbb749011a..813ea10fdde 100644
--- a/fs/autofs4/waitq.c
+++ b/fs/autofs4/waitq.c
@@ -91,23 +91,6 @@ static int autofs4_write(struct file *file, const void *addr, int bytes)
91 return (bytes > 0); 91 return (bytes > 0);
92} 92}
93 93
94/*
95 * The autofs_v5 packet was misdesigned.
96 *
97 * The packets are identical on x86-32 and x86-64, but have different
98 * alignment. Which means that 'sizeof()' will give different results.
99 * Fix it up for the case of running 32-bit user mode on a 64-bit kernel.
100 */
101static noinline size_t autofs_v5_packet_size(struct autofs_sb_info *sbi)
102{
103 size_t pktsz = sizeof(struct autofs_v5_packet);
104#if defined(CONFIG_X86_64) && defined(CONFIG_COMPAT)
105 if (sbi->compat_daemon > 0)
106 pktsz -= 4;
107#endif
108 return pktsz;
109}
110
111static void autofs4_notify_daemon(struct autofs_sb_info *sbi, 94static void autofs4_notify_daemon(struct autofs_sb_info *sbi,
112 struct autofs_wait_queue *wq, 95 struct autofs_wait_queue *wq,
113 int type) 96 int type)
@@ -164,7 +147,8 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi,
164 { 147 {
165 struct autofs_v5_packet *packet = &pkt.v5_pkt.v5_packet; 148 struct autofs_v5_packet *packet = &pkt.v5_pkt.v5_packet;
166 149
167 pktsz = autofs_v5_packet_size(sbi); 150 pktsz = sizeof(*packet);
151
168 packet->wait_queue_token = wq->wait_queue_token; 152 packet->wait_queue_token = wq->wait_queue_token;
169 packet->len = wq->name.len; 153 packet->len = wq->name.len;
170 memcpy(packet->name, wq->name.name, wq->name.len); 154 memcpy(packet->name, wq->name.name, wq->name.len);