diff options
| author | Ian Kent <raven@themaw.net> | 2006-03-27 04:14:55 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-27 11:44:40 -0500 |
| commit | 5c0a32fc2cd0be912511199449a37a4a6f0f582d (patch) | |
| tree | f34ff979282bd957dee161e3668cc01b2dbd51ee | |
| parent | 3a15e2ab5d6e79a79291734ac24f33d51c0ae389 (diff) | |
[PATCH] autofs4: add new packet type for v5 communications
This patch define a new autofs packet for autofs v5 and updates the waitq.c
functions to handle the additional packet type.
Signed-off-by: Ian Kent <raven@themaw.net>
Cc: Al Viro <viro@ftp.linux.org.uk>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
| -rw-r--r-- | fs/autofs4/autofs_i.h | 23 | ||||
| -rw-r--r-- | fs/autofs4/waitq.c | 86 | ||||
| -rw-r--r-- | include/linux/auto_fs4.h | 51 |
3 files changed, 136 insertions, 24 deletions
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h index ed388a1d8fc4..37c8d909d1e9 100644 --- a/fs/autofs4/autofs_i.h +++ b/fs/autofs4/autofs_i.h | |||
| @@ -77,6 +77,12 @@ struct autofs_wait_queue { | |||
| 77 | int hash; | 77 | int hash; |
| 78 | int len; | 78 | int len; |
| 79 | char *name; | 79 | char *name; |
| 80 | u32 dev; | ||
| 81 | u64 ino; | ||
| 82 | uid_t uid; | ||
| 83 | gid_t gid; | ||
| 84 | pid_t pid; | ||
| 85 | pid_t tgid; | ||
| 80 | /* This is for status reporting upon return */ | 86 | /* This is for status reporting upon return */ |
| 81 | int status; | 87 | int status; |
| 82 | atomic_t notified; | 88 | atomic_t notified; |
| @@ -180,13 +186,6 @@ struct autofs_info *autofs4_init_ino(struct autofs_info *, struct autofs_sb_info | |||
| 180 | 186 | ||
| 181 | /* Queue management functions */ | 187 | /* Queue management functions */ |
| 182 | 188 | ||
| 183 | enum autofs_notify | ||
| 184 | { | ||
| 185 | NFY_NONE, | ||
| 186 | NFY_MOUNT, | ||
| 187 | NFY_EXPIRE | ||
| 188 | }; | ||
| 189 | |||
| 190 | int autofs4_wait(struct autofs_sb_info *,struct dentry *, enum autofs_notify); | 189 | int autofs4_wait(struct autofs_sb_info *,struct dentry *, enum autofs_notify); |
| 191 | int autofs4_wait_release(struct autofs_sb_info *,autofs_wqt_t,int); | 190 | int autofs4_wait_release(struct autofs_sb_info *,autofs_wqt_t,int); |
| 192 | void autofs4_catatonic_mode(struct autofs_sb_info *); | 191 | void autofs4_catatonic_mode(struct autofs_sb_info *); |
| @@ -204,6 +203,16 @@ static inline int autofs4_follow_mount(struct vfsmount **mnt, struct dentry **de | |||
| 204 | return res; | 203 | return res; |
| 205 | } | 204 | } |
| 206 | 205 | ||
| 206 | static inline u32 autofs4_get_dev(struct autofs_sb_info *sbi) | ||
| 207 | { | ||
| 208 | return new_encode_dev(sbi->sb->s_dev); | ||
| 209 | } | ||
| 210 | |||
| 211 | static inline u64 autofs4_get_ino(struct autofs_sb_info *sbi) | ||
| 212 | { | ||
| 213 | return sbi->sb->s_root->d_inode->i_ino; | ||
| 214 | } | ||
| 215 | |||
| 207 | static inline int simple_positive(struct dentry *dentry) | 216 | static inline int simple_positive(struct dentry *dentry) |
| 208 | { | 217 | { |
| 209 | return dentry->d_inode && !d_unhashed(dentry); | 218 | return dentry->d_inode && !d_unhashed(dentry); |
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c index b0bb9d43bcd9..12da2c977b0a 100644 --- a/fs/autofs4/waitq.c +++ b/fs/autofs4/waitq.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * linux/fs/autofs/waitq.c | 3 | * linux/fs/autofs/waitq.c |
| 4 | * | 4 | * |
| 5 | * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved | 5 | * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved |
| 6 | * Copyright 2001-2003 Ian Kent <raven@themaw.net> | 6 | * Copyright 2001-2006 Ian Kent <raven@themaw.net> |
| 7 | * | 7 | * |
| 8 | * This file is part of the Linux kernel and is made available under | 8 | * This file is part of the Linux kernel and is made available under |
| 9 | * the terms of the GNU General Public License, version 2, or at your | 9 | * the terms of the GNU General Public License, version 2, or at your |
| @@ -97,7 +97,10 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi, | |||
| 97 | 97 | ||
| 98 | pkt.hdr.proto_version = sbi->version; | 98 | pkt.hdr.proto_version = sbi->version; |
| 99 | pkt.hdr.type = type; | 99 | pkt.hdr.type = type; |
| 100 | if (type == autofs_ptype_missing) { | 100 | switch (type) { |
| 101 | /* Kernel protocol v4 missing and expire packets */ | ||
| 102 | case autofs_ptype_missing: | ||
| 103 | { | ||
| 101 | struct autofs_packet_missing *mp = &pkt.missing; | 104 | struct autofs_packet_missing *mp = &pkt.missing; |
| 102 | 105 | ||
| 103 | pktsz = sizeof(*mp); | 106 | pktsz = sizeof(*mp); |
| @@ -106,7 +109,10 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi, | |||
| 106 | mp->len = wq->len; | 109 | mp->len = wq->len; |
| 107 | memcpy(mp->name, wq->name, wq->len); | 110 | memcpy(mp->name, wq->name, wq->len); |
| 108 | mp->name[wq->len] = '\0'; | 111 | mp->name[wq->len] = '\0'; |
| 109 | } else if (type == autofs_ptype_expire_multi) { | 112 | break; |
| 113 | } | ||
| 114 | case autofs_ptype_expire_multi: | ||
| 115 | { | ||
| 110 | struct autofs_packet_expire_multi *ep = &pkt.expire_multi; | 116 | struct autofs_packet_expire_multi *ep = &pkt.expire_multi; |
| 111 | 117 | ||
| 112 | pktsz = sizeof(*ep); | 118 | pktsz = sizeof(*ep); |
| @@ -115,7 +121,34 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi, | |||
| 115 | ep->len = wq->len; | 121 | ep->len = wq->len; |
| 116 | memcpy(ep->name, wq->name, wq->len); | 122 | memcpy(ep->name, wq->name, wq->len); |
| 117 | ep->name[wq->len] = '\0'; | 123 | ep->name[wq->len] = '\0'; |
| 118 | } else { | 124 | break; |
| 125 | } | ||
| 126 | /* | ||
| 127 | * Kernel protocol v5 packet for handling indirect and direct | ||
| 128 | * mount missing and expire requests | ||
| 129 | */ | ||
| 130 | case autofs_ptype_missing_indirect: | ||
| 131 | case autofs_ptype_expire_indirect: | ||
| 132 | case autofs_ptype_missing_direct: | ||
| 133 | case autofs_ptype_expire_direct: | ||
| 134 | { | ||
| 135 | struct autofs_v5_packet *packet = &pkt.v5_packet; | ||
| 136 | |||
| 137 | pktsz = sizeof(*packet); | ||
| 138 | |||
| 139 | packet->wait_queue_token = wq->wait_queue_token; | ||
| 140 | packet->len = wq->len; | ||
| 141 | memcpy(packet->name, wq->name, wq->len); | ||
| 142 | packet->name[wq->len] = '\0'; | ||
| 143 | packet->dev = wq->dev; | ||
| 144 | packet->ino = wq->ino; | ||
| 145 | packet->uid = wq->uid; | ||
| 146 | packet->gid = wq->gid; | ||
| 147 | packet->pid = wq->pid; | ||
| 148 | packet->tgid = wq->tgid; | ||
| 149 | break; | ||
| 150 | } | ||
| 151 | default: | ||
| 119 | printk("autofs4_notify_daemon: bad type %d!\n", type); | 152 | printk("autofs4_notify_daemon: bad type %d!\n", type); |
| 120 | return; | 153 | return; |
| 121 | } | 154 | } |
| @@ -161,7 +194,9 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry, | |||
| 161 | { | 194 | { |
| 162 | struct autofs_wait_queue *wq; | 195 | struct autofs_wait_queue *wq; |
| 163 | char *name; | 196 | char *name; |
| 164 | int len, status; | 197 | unsigned int len = 0; |
| 198 | unsigned int hash = 0; | ||
| 199 | int status; | ||
| 165 | 200 | ||
| 166 | /* In catatonic mode, we don't wait for nobody */ | 201 | /* In catatonic mode, we don't wait for nobody */ |
| 167 | if (sbi->catatonic) | 202 | if (sbi->catatonic) |
| @@ -171,11 +206,17 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry, | |||
| 171 | if (!name) | 206 | if (!name) |
| 172 | return -ENOMEM; | 207 | return -ENOMEM; |
| 173 | 208 | ||
| 174 | len = autofs4_getpath(sbi, dentry, &name); | 209 | /* If this is a direct mount request create a dummy name */ |
| 175 | if (!len) { | 210 | if (IS_ROOT(dentry) && (sbi->type & AUTOFS_TYP_DIRECT)) |
| 176 | kfree(name); | 211 | len = sprintf(name, "%p", dentry); |
| 177 | return -ENOENT; | 212 | else { |
| 213 | len = autofs4_getpath(sbi, dentry, &name); | ||
| 214 | if (!len) { | ||
| 215 | kfree(name); | ||
| 216 | return -ENOENT; | ||
| 217 | } | ||
| 178 | } | 218 | } |
| 219 | hash = full_name_hash(name, len); | ||
| 179 | 220 | ||
| 180 | if (mutex_lock_interruptible(&sbi->wq_mutex)) { | 221 | if (mutex_lock_interruptible(&sbi->wq_mutex)) { |
| 181 | kfree(name); | 222 | kfree(name); |
| @@ -211,9 +252,15 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry, | |||
| 211 | wq->next = sbi->queues; | 252 | wq->next = sbi->queues; |
| 212 | sbi->queues = wq; | 253 | sbi->queues = wq; |
| 213 | init_waitqueue_head(&wq->queue); | 254 | init_waitqueue_head(&wq->queue); |
| 214 | wq->hash = dentry->d_name.hash; | 255 | wq->hash = hash; |
| 215 | wq->name = name; | 256 | wq->name = name; |
| 216 | wq->len = len; | 257 | wq->len = len; |
| 258 | wq->dev = autofs4_get_dev(sbi); | ||
| 259 | wq->ino = autofs4_get_ino(sbi); | ||
| 260 | wq->uid = current->uid; | ||
| 261 | wq->gid = current->gid; | ||
| 262 | wq->pid = current->pid; | ||
| 263 | wq->tgid = current->tgid; | ||
| 217 | wq->status = -EINTR; /* Status return if interrupted */ | 264 | wq->status = -EINTR; /* Status return if interrupted */ |
| 218 | atomic_set(&wq->wait_ctr, 2); | 265 | atomic_set(&wq->wait_ctr, 2); |
| 219 | atomic_set(&wq->notified, 1); | 266 | atomic_set(&wq->notified, 1); |
| @@ -227,8 +274,23 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry, | |||
| 227 | } | 274 | } |
| 228 | 275 | ||
| 229 | if (notify != NFY_NONE && atomic_dec_and_test(&wq->notified)) { | 276 | if (notify != NFY_NONE && atomic_dec_and_test(&wq->notified)) { |
| 230 | int type = (notify == NFY_MOUNT ? | 277 | int type; |
| 231 | autofs_ptype_missing : autofs_ptype_expire_multi); | 278 | |
| 279 | if (sbi->version < 5) { | ||
| 280 | if (notify == NFY_MOUNT) | ||
| 281 | type = autofs_ptype_missing; | ||
| 282 | else | ||
| 283 | type = autofs_ptype_expire_multi; | ||
| 284 | } else { | ||
| 285 | if (notify == NFY_MOUNT) | ||
| 286 | type = (sbi->type & AUTOFS_TYP_DIRECT) ? | ||
| 287 | autofs_ptype_missing_direct : | ||
| 288 | autofs_ptype_missing_indirect; | ||
| 289 | else | ||
| 290 | type = (sbi->type & AUTOFS_TYP_DIRECT) ? | ||
| 291 | autofs_ptype_expire_direct : | ||
| 292 | autofs_ptype_expire_indirect; | ||
| 293 | } | ||
| 232 | 294 | ||
| 233 | DPRINTK("new wait id = 0x%08lx, name = %.*s, nfy=%d\n", | 295 | DPRINTK("new wait id = 0x%08lx, name = %.*s, nfy=%d\n", |
| 234 | (unsigned long) wq->wait_queue_token, wq->len, wq->name, notify); | 296 | (unsigned long) wq->wait_queue_token, wq->len, wq->name, notify); |
diff --git a/include/linux/auto_fs4.h b/include/linux/auto_fs4.h index d998ddcf7288..0a6bc52ffe88 100644 --- a/include/linux/auto_fs4.h +++ b/include/linux/auto_fs4.h | |||
| @@ -19,18 +19,37 @@ | |||
| 19 | #undef AUTOFS_MIN_PROTO_VERSION | 19 | #undef AUTOFS_MIN_PROTO_VERSION |
| 20 | #undef AUTOFS_MAX_PROTO_VERSION | 20 | #undef AUTOFS_MAX_PROTO_VERSION |
| 21 | 21 | ||
| 22 | #define AUTOFS_PROTO_VERSION 4 | 22 | #define AUTOFS_PROTO_VERSION 5 |
| 23 | #define AUTOFS_MIN_PROTO_VERSION 3 | 23 | #define AUTOFS_MIN_PROTO_VERSION 3 |
| 24 | #define AUTOFS_MAX_PROTO_VERSION 4 | 24 | #define AUTOFS_MAX_PROTO_VERSION 5 |
| 25 | 25 | ||
| 26 | #define AUTOFS_PROTO_SUBVERSION 10 | 26 | #define AUTOFS_PROTO_SUBVERSION 0 |
| 27 | 27 | ||
| 28 | /* Mask for expire behaviour */ | 28 | /* Mask for expire behaviour */ |
| 29 | #define AUTOFS_EXP_IMMEDIATE 1 | 29 | #define AUTOFS_EXP_IMMEDIATE 1 |
| 30 | #define AUTOFS_EXP_LEAVES 2 | 30 | #define AUTOFS_EXP_LEAVES 2 |
| 31 | 31 | ||
| 32 | /* New message type */ | 32 | /* Daemon notification packet types */ |
| 33 | #define autofs_ptype_expire_multi 2 /* Expire entry (umount request) */ | 33 | enum autofs_notify { |
| 34 | NFY_NONE, | ||
| 35 | NFY_MOUNT, | ||
| 36 | NFY_EXPIRE | ||
| 37 | }; | ||
| 38 | |||
| 39 | /* Kernel protocol version 4 packet types */ | ||
| 40 | |||
| 41 | /* Expire entry (umount request) */ | ||
| 42 | #define autofs_ptype_expire_multi 2 | ||
| 43 | |||
| 44 | /* Kernel protocol version 5 packet types */ | ||
| 45 | |||
| 46 | /* Indirect mount missing and expire requests. */ | ||
| 47 | #define autofs_ptype_missing_indirect 3 | ||
| 48 | #define autofs_ptype_expire_indirect 4 | ||
| 49 | |||
| 50 | /* Direct mount missing and expire requests */ | ||
| 51 | #define autofs_ptype_missing_direct 5 | ||
| 52 | #define autofs_ptype_expire_direct 6 | ||
| 34 | 53 | ||
| 35 | /* v4 multi expire (via pipe) */ | 54 | /* v4 multi expire (via pipe) */ |
| 36 | struct autofs_packet_expire_multi { | 55 | struct autofs_packet_expire_multi { |
| @@ -40,14 +59,36 @@ struct autofs_packet_expire_multi { | |||
| 40 | char name[NAME_MAX+1]; | 59 | char name[NAME_MAX+1]; |
| 41 | }; | 60 | }; |
| 42 | 61 | ||
| 62 | /* autofs v5 common packet struct */ | ||
| 63 | struct autofs_v5_packet { | ||
| 64 | struct autofs_packet_hdr hdr; | ||
| 65 | autofs_wqt_t wait_queue_token; | ||
| 66 | __u32 dev; | ||
| 67 | __u64 ino; | ||
| 68 | __u32 uid; | ||
| 69 | __u32 gid; | ||
| 70 | __u32 pid; | ||
| 71 | __u32 tgid; | ||
| 72 | __u32 len; | ||
| 73 | char name[NAME_MAX+1]; | ||
| 74 | }; | ||
| 75 | |||
| 76 | typedef struct autofs_v5_packet autofs_packet_missing_indirect_t; | ||
| 77 | typedef struct autofs_v5_packet autofs_packet_expire_indirect_t; | ||
| 78 | typedef struct autofs_v5_packet autofs_packet_missing_direct_t; | ||
| 79 | typedef struct autofs_v5_packet autofs_packet_expire_direct_t; | ||
| 80 | |||
| 43 | union autofs_packet_union { | 81 | union autofs_packet_union { |
| 44 | struct autofs_packet_hdr hdr; | 82 | struct autofs_packet_hdr hdr; |
| 45 | struct autofs_packet_missing missing; | 83 | struct autofs_packet_missing missing; |
| 46 | struct autofs_packet_expire expire; | 84 | struct autofs_packet_expire expire; |
| 47 | struct autofs_packet_expire_multi expire_multi; | 85 | struct autofs_packet_expire_multi expire_multi; |
| 86 | struct autofs_v5_packet v5_packet; | ||
| 48 | }; | 87 | }; |
| 49 | 88 | ||
| 50 | #define AUTOFS_IOC_EXPIRE_MULTI _IOW(0x93,0x66,int) | 89 | #define AUTOFS_IOC_EXPIRE_MULTI _IOW(0x93,0x66,int) |
| 90 | #define AUTOFS_IOC_EXPIRE_INDIRECT AUTOFS_IOC_EXPIRE_MULTI | ||
| 91 | #define AUTOFS_IOC_EXPIRE_DIRECT AUTOFS_IOC_EXPIRE_MULTI | ||
| 51 | #define AUTOFS_IOC_PROTOSUBVER _IOR(0x93,0x67,int) | 92 | #define AUTOFS_IOC_PROTOSUBVER _IOR(0x93,0x67,int) |
| 52 | #define AUTOFS_IOC_ASKREGHOST _IOR(0x93,0x68,int) | 93 | #define AUTOFS_IOC_ASKREGHOST _IOR(0x93,0x68,int) |
| 53 | #define AUTOFS_IOC_TOGGLEREGHOST _IOR(0x93,0x69,int) | 94 | #define AUTOFS_IOC_TOGGLEREGHOST _IOR(0x93,0x69,int) |
