Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Revert "autofs: work around unhappy compat problem on x86-64"

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>
Cc: stable@kernel.org # for 3.3
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

+3 -23
-1
fs/autofs4/autofs_i.h
··· 110 110 int sub_version; 111 111 int min_proto; 112 112 int max_proto; 113 - int compat_daemon; 114 113 unsigned long exp_timeout; 115 114 unsigned int type; 116 115 int reghost_enabled;
-1
fs/autofs4/dev-ioctl.c
··· 385 385 sbi->pipefd = pipefd; 386 386 sbi->pipe = pipe; 387 387 sbi->catatonic = 0; 388 - sbi->compat_daemon = is_compat_task(); 389 388 } 390 389 out: 391 390 mutex_unlock(&sbi->wq_mutex);
-2
fs/autofs4/inode.c
··· 19 19 #include <linux/parser.h> 20 20 #include <linux/bitops.h> 21 21 #include <linux/magic.h> 22 - #include <linux/compat.h> 23 22 #include "autofs_i.h" 24 23 #include <linux/module.h> 25 24 ··· 224 225 set_autofs_type_indirect(&sbi->type); 225 226 sbi->min_proto = 0; 226 227 sbi->max_proto = 0; 227 - sbi->compat_daemon = is_compat_task(); 228 228 mutex_init(&sbi->wq_mutex); 229 229 mutex_init(&sbi->pipe_mutex); 230 230 spin_lock_init(&sbi->fs_lock);
+3 -19
fs/autofs4/waitq.c
··· 91 91 92 92 return (bytes > 0); 93 93 } 94 - 95 - /* 96 - * The autofs_v5 packet was misdesigned. 97 - * 98 - * The packets are identical on x86-32 and x86-64, but have different 99 - * alignment. Which means that 'sizeof()' will give different results. 100 - * Fix it up for the case of running 32-bit user mode on a 64-bit kernel. 101 - */ 102 - static noinline size_t autofs_v5_packet_size(struct autofs_sb_info *sbi) 103 - { 104 - size_t pktsz = sizeof(struct autofs_v5_packet); 105 - #if defined(CONFIG_X86_64) && defined(CONFIG_COMPAT) 106 - if (sbi->compat_daemon > 0) 107 - pktsz -= 4; 108 - #endif 109 - return pktsz; 110 - } 111 - 94 + 112 95 static void autofs4_notify_daemon(struct autofs_sb_info *sbi, 113 96 struct autofs_wait_queue *wq, 114 97 int type) ··· 155 172 { 156 173 struct autofs_v5_packet *packet = &pkt.v5_pkt.v5_packet; 157 174 158 - pktsz = autofs_v5_packet_size(sbi); 175 + pktsz = sizeof(*packet); 176 + 159 177 packet->wait_queue_token = wq->wait_queue_token; 160 178 packet->len = wq->name.len; 161 179 memcpy(packet->name, wq->name.name, wq->name.len);