[PATCH] Add autofs_v6_packet with same packet size on x86 and x86_64.
Thomas Meyer
thomas at m3y3r.de
Sun Nov 13 04:13:57 PST 2011
autofs_v5_packet is 300 bytes on x86 and 304 bytes on x86_64.
This leads to an error in at least systemd when running a x86_64 kernel
on an x86 userspace. Fix this by adding a new protocol version 6 packet
that has the same size on x86 and x86_64.
Signed-off-by: Thomas Meyer <thomas at m3y3r.de>
---
fs/autofs4/inode.c | 30 ++++++++++++++++++++++------
fs/autofs4/waitq.c | 47 +++++++++++++++++++++++++++++++--------------
include/linux/auto_fs4.h | 19 ++++++++++++++++-
3 files changed, 72 insertions(+), 24 deletions(-)
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index 8179f1a..10a57fc 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -197,6 +197,28 @@ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
return (*pipefd < 0);
}
+static bool check_protocol_version(int minproto, int maxproto)
+{
+ bool rc = true;
+
+ if (minproto > maxproto || maxproto < minproto) {
+ printk("autofs: protocol min(%d)/max(%d) version error!",
+ minproto, maxproto);
+ rc = false;
+ }
+
+ if (maxproto < AUTOFS_MIN_PROTO_VERSION ||
+ minproto > AUTOFS_MAX_PROTO_VERSION) {
+ printk("autofs: kernel does not match daemon version "
+ "daemon (%d, %d) kernel (%d, %d)\n",
+ minproto, maxproto,
+ AUTOFS_MIN_PROTO_VERSION, AUTOFS_MAX_PROTO_VERSION);
+ rc = false;
+ }
+
+ return rc;
+}
+
int autofs4_fill_super(struct super_block *s, void *data, int silent)
{
struct inode * root_inode;
@@ -269,14 +291,8 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
root_inode->i_op = &autofs4_dir_inode_operations;
/* Couldn't this be tested earlier? */
- if (sbi->max_proto < AUTOFS_MIN_PROTO_VERSION ||
- sbi->min_proto > AUTOFS_MAX_PROTO_VERSION) {
- printk("autofs: kernel does not match daemon version "
- "daemon (%d, %d) kernel (%d, %d)\n",
- sbi->min_proto, sbi->max_proto,
- AUTOFS_MIN_PROTO_VERSION, AUTOFS_MAX_PROTO_VERSION);
+ if(check_protocol_version(sbi->min_proto, sbi->max_proto) == false)
goto fail_dput;
- }
/* Establish highest kernel protocol version */
if (sbi->max_proto > AUTOFS_MAX_PROTO_VERSION)
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
index e1fbdee..2e455be 100644
--- a/fs/autofs4/waitq.c
+++ b/fs/autofs4/waitq.c
@@ -99,6 +99,7 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi,
struct autofs_packet_hdr hdr;
union autofs_packet_union v4_pkt;
union autofs_v5_packet_union v5_pkt;
+ struct autofs_v6_packet v6_pkt;
} pkt;
struct file *pipe = NULL;
size_t pktsz;
@@ -137,7 +138,7 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi,
break;
}
/*
- * Kernel protocol v5 packet for handling indirect and direct
+ * Kernel protocol v5/v6 packet for handling indirect and direct
* mount missing and expire requests
*/
case autofs_ptype_missing_indirect:
@@ -145,20 +146,36 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi,
case autofs_ptype_missing_direct:
case autofs_ptype_expire_direct:
{
- struct autofs_v5_packet *packet = &pkt.v5_pkt.v5_packet;
-
- pktsz = sizeof(*packet);
-
- packet->wait_queue_token = wq->wait_queue_token;
- packet->len = wq->name.len;
- memcpy(packet->name, wq->name.name, wq->name.len);
- packet->name[wq->name.len] = '\0';
- packet->dev = wq->dev;
- packet->ino = wq->ino;
- packet->uid = wq->uid;
- packet->gid = wq->gid;
- packet->pid = wq->pid;
- packet->tgid = wq->tgid;
+ if(sbi->version == 5) {
+ struct autofs_v5_packet *packet = &pkt.v5_pkt.v5_packet;
+
+ packet->wait_queue_token = wq->wait_queue_token;
+ packet->len = wq->name.len;
+ memcpy(packet->name, wq->name.name, wq->name.len);
+ packet->name[wq->name.len] = '\0';
+ packet->dev = wq->dev;
+ packet->ino = wq->ino;
+ packet->uid = wq->uid;
+ packet->gid = wq->gid;
+ packet->pid = wq->pid;
+ packet->tgid = wq->tgid;
+ pktsz = sizeof(packet);
+ }
+ if(sbi->version == 6) {
+ struct autofs_v6_packet *packet = &pkt.v6_pkt;
+
+ packet->wait_queue_token = wq->wait_queue_token;
+ packet->len = wq->name.len;
+ memcpy(packet->name, wq->name.name, wq->name.len);
+ packet->name[wq->name.len] = '\0';
+ packet->dev = wq->dev;
+ packet->ino = wq->ino;
+ packet->uid = wq->uid;
+ packet->gid = wq->gid;
+ packet->pid = wq->pid;
+ packet->tgid = wq->tgid;
+ pktsz = sizeof(packet);
+ }
break;
}
default:
diff --git a/include/linux/auto_fs4.h b/include/linux/auto_fs4.h
index e02982f..e16b105 100644
--- a/include/linux/auto_fs4.h
+++ b/include/linux/auto_fs4.h
@@ -20,9 +20,9 @@
#undef AUTOFS_MIN_PROTO_VERSION
#undef AUTOFS_MAX_PROTO_VERSION
-#define AUTOFS_PROTO_VERSION 5
+#define AUTOFS_PROTO_VERSION 6
#define AUTOFS_MIN_PROTO_VERSION 3
-#define AUTOFS_MAX_PROTO_VERSION 5
+#define AUTOFS_MAX_PROTO_VERSION 6
#define AUTOFS_PROTO_SUBVERSION 2
@@ -154,6 +154,21 @@ union autofs_v5_packet_union {
autofs_packet_expire_direct_t expire_direct;
};
+/* autofs v6 common packet struct */
+/* packed structure for same packet size on x86 and x86_64 */
+struct autofs_v6_packet {
+ struct autofs_packet_hdr hdr;
+ autofs_wqt_t wait_queue_token;
+ __u32 dev;
+ __u64 ino;
+ __u32 uid;
+ __u32 gid;
+ __u32 pid;
+ __u32 tgid;
+ __u32 len;
+ char name[NAME_MAX+1];
+} __attribute__ ((packed));
+
#define AUTOFS_IOC_EXPIRE_MULTI _IOW(0x93,0x66,int)
#define AUTOFS_IOC_EXPIRE_INDIRECT AUTOFS_IOC_EXPIRE_MULTI
#define AUTOFS_IOC_EXPIRE_DIRECT AUTOFS_IOC_EXPIRE_MULTI
--
1.7.7.1
More information about the systemd-devel
mailing list