aboutsummaryrefslogtreecommitdiffstats
path: root/fs/autofs
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2010-10-04 16:28:10 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-10-05 12:03:39 -0400
commitdb7bee24d23d82cc55c7cbc9a1f82d07066d6fce (patch)
tree4d92f11d078be04f1810a9d099140eebc890772d /fs/autofs
parentd95ec7e2fd5cebf2f1caf3f572fa5e0a820ac5b1 (diff)
autofs3: move to drivers/staging
Nobody appears to be interested in fixing autofs3 bugs any more and it uses the BKL, which is going away. Move this to staging for retirement. Unless someone complains until 2.6.38, we can remove it for good. The include/linux/auto_fs.h header file is still used by autofs4, so it remains in place. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Cc: Ian Kent <raven@themaw.net> Cc: autofs@linux.kernel.org Cc: "H. Peter Anvin" <hpa@zytor.com> Acked-by: H. Peter Anvin <hpa@zytor.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'fs/autofs')
-rw-r--r--fs/autofs/Kconfig21
-rw-r--r--fs/autofs/Makefile7
-rw-r--r--fs/autofs/autofs_i.h165
-rw-r--r--fs/autofs/dirhash.c250
-rw-r--r--fs/autofs/init.c52
-rw-r--r--fs/autofs/inode.c288
-rw-r--r--fs/autofs/root.c643
-rw-r--r--fs/autofs/symlink.c26
-rw-r--r--fs/autofs/waitq.c205
9 files changed, 0 insertions, 1657 deletions
diff --git a/fs/autofs/Kconfig b/fs/autofs/Kconfig
deleted file mode 100644
index 5f3bea90911e..000000000000
--- a/fs/autofs/Kconfig
+++ /dev/null
@@ -1,21 +0,0 @@
1config AUTOFS_FS
2 tristate "Kernel automounter support"
3 help
4 The automounter is a tool to automatically mount remote file systems
5 on demand. This implementation is partially kernel-based to reduce
6 overhead in the already-mounted case; this is unlike the BSD
7 automounter (amd), which is a pure user space daemon.
8
9 To use the automounter you need the user-space tools from the autofs
10 package; you can find the location in <file:Documentation/Changes>.
11 You also want to answer Y to "NFS file system support", below.
12
13 If you want to use the newer version of the automounter with more
14 features, say N here and say Y to "Kernel automounter v4 support",
15 below.
16
17 To compile this support as a module, choose M here: the module will be
18 called autofs.
19
20 If you are not a part of a fairly large, distributed network, you
21 probably do not need an automounter, and can say N here.
diff --git a/fs/autofs/Makefile b/fs/autofs/Makefile
deleted file mode 100644
index 453a60f46d05..000000000000
--- a/fs/autofs/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
1#
2# Makefile for the linux autofs-filesystem routines.
3#
4
5obj-$(CONFIG_AUTOFS_FS) += autofs.o
6
7autofs-objs := dirhash.o init.o inode.o root.o symlink.o waitq.o
diff --git a/fs/autofs/autofs_i.h b/fs/autofs/autofs_i.h
deleted file mode 100644
index 901a3e67ec45..000000000000
--- a/fs/autofs/autofs_i.h
+++ /dev/null
@@ -1,165 +0,0 @@
1/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * linux/fs/autofs/autofs_i.h
4 *
5 * Copyright 1997-1998 Transmeta Corporation - All Rights Reserved
6 *
7 * This file is part of the Linux kernel and is made available under
8 * the terms of the GNU General Public License, version 2, or at your
9 * option, any later version, incorporated herein by reference.
10 *
11 * ----------------------------------------------------------------------- */
12
13/* Internal header file for autofs */
14
15#include <linux/auto_fs.h>
16
17/* This is the range of ioctl() numbers we claim as ours */
18#define AUTOFS_IOC_FIRST AUTOFS_IOC_READY
19#define AUTOFS_IOC_COUNT 32
20
21#include <linux/kernel.h>
22#include <linux/slab.h>
23#include <linux/time.h>
24#include <linux/string.h>
25#include <linux/wait.h>
26#include <linux/dcache.h>
27#include <linux/namei.h>
28#include <linux/mount.h>
29#include <linux/sched.h>
30
31#include <asm/current.h>
32#include <asm/uaccess.h>
33
34#ifdef DEBUG
35#define DPRINTK(D) (printk D)
36#else
37#define DPRINTK(D) ((void)0)
38#endif
39
40/*
41 * If the daemon returns a negative response (AUTOFS_IOC_FAIL) then the
42 * kernel will keep the negative response cached for up to the time given
43 * here, although the time can be shorter if the kernel throws the dcache
44 * entry away. This probably should be settable from user space.
45 */
46#define AUTOFS_NEGATIVE_TIMEOUT (60*HZ) /* 1 minute */
47
48/* Structures associated with the root directory hash table */
49
50#define AUTOFS_HASH_SIZE 67
51
52struct autofs_dir_ent {
53 int hash;
54 char *name;
55 int len;
56 ino_t ino;
57 struct dentry *dentry;
58 /* Linked list of entries */
59 struct autofs_dir_ent *next;
60 struct autofs_dir_ent **back;
61 /* The following entries are for the expiry system */
62 unsigned long last_usage;
63 struct list_head exp;
64};
65
66struct autofs_dirhash {
67 struct autofs_dir_ent *h[AUTOFS_HASH_SIZE];
68 struct list_head expiry_head;
69};
70
71struct autofs_wait_queue {
72 wait_queue_head_t queue;
73 struct autofs_wait_queue *next;
74 autofs_wqt_t wait_queue_token;
75 /* We use the following to see what we are waiting for */
76 int hash;
77 int len;
78 char *name;
79 /* This is for status reporting upon return */
80 int status;
81 int wait_ctr;
82};
83
84struct autofs_symlink {
85 char *data;
86 int len;
87 time_t mtime;
88};
89
90#define AUTOFS_MAX_SYMLINKS 256
91
92#define AUTOFS_ROOT_INO 1
93#define AUTOFS_FIRST_SYMLINK 2
94#define AUTOFS_FIRST_DIR_INO (AUTOFS_FIRST_SYMLINK+AUTOFS_MAX_SYMLINKS)
95
96#define AUTOFS_SYMLINK_BITMAP_LEN \
97 ((AUTOFS_MAX_SYMLINKS+((sizeof(long)*1)-1))/(sizeof(long)*8))
98
99#define AUTOFS_SBI_MAGIC 0x6d4a556d
100
101struct autofs_sb_info {
102 u32 magic;
103 struct file *pipe;
104 struct pid *oz_pgrp;
105 int catatonic;
106 struct super_block *sb;
107 unsigned long exp_timeout;
108 ino_t next_dir_ino;
109 struct autofs_wait_queue *queues; /* Wait queue pointer */
110 struct autofs_dirhash dirhash; /* Root directory hash */
111 struct autofs_symlink symlink[AUTOFS_MAX_SYMLINKS];
112 unsigned long symlink_bitmap[AUTOFS_SYMLINK_BITMAP_LEN];
113};
114
115static inline struct autofs_sb_info *autofs_sbi(struct super_block *sb)
116{
117 return (struct autofs_sb_info *)(sb->s_fs_info);
118}
119
120/* autofs_oz_mode(): do we see the man behind the curtain? (The
121 processes which do manipulations for us in user space sees the raw
122 filesystem without "magic".) */
123
124static inline int autofs_oz_mode(struct autofs_sb_info *sbi) {
125 return sbi->catatonic || task_pgrp(current) == sbi->oz_pgrp;
126}
127
128/* Hash operations */
129
130void autofs_initialize_hash(struct autofs_dirhash *);
131struct autofs_dir_ent *autofs_hash_lookup(const struct autofs_dirhash *,struct qstr *);
132void autofs_hash_insert(struct autofs_dirhash *,struct autofs_dir_ent *);
133void autofs_hash_delete(struct autofs_dir_ent *);
134struct autofs_dir_ent *autofs_hash_enum(const struct autofs_dirhash *,off_t *,struct autofs_dir_ent *);
135void autofs_hash_dputall(struct autofs_dirhash *);
136void autofs_hash_nuke(struct autofs_sb_info *);
137
138/* Expiration-handling functions */
139
140void autofs_update_usage(struct autofs_dirhash *,struct autofs_dir_ent *);
141struct autofs_dir_ent *autofs_expire(struct super_block *,struct autofs_sb_info *, struct vfsmount *mnt);
142
143/* Operations structures */
144
145extern const struct inode_operations autofs_root_inode_operations;
146extern const struct inode_operations autofs_symlink_inode_operations;
147extern const struct file_operations autofs_root_operations;
148
149/* Initializing function */
150
151int autofs_fill_super(struct super_block *, void *, int);
152void autofs_kill_sb(struct super_block *sb);
153struct inode *autofs_iget(struct super_block *, unsigned long);
154
155/* Queue management functions */
156
157int autofs_wait(struct autofs_sb_info *,struct qstr *);
158int autofs_wait_release(struct autofs_sb_info *,autofs_wqt_t,int);
159void autofs_catatonic_mode(struct autofs_sb_info *);
160
161#ifdef DEBUG
162void autofs_say(const char *name, int len);
163#else
164#define autofs_say(n,l) ((void)0)
165#endif
diff --git a/fs/autofs/dirhash.c b/fs/autofs/dirhash.c
deleted file mode 100644
index e947915109e5..000000000000
--- a/fs/autofs/dirhash.c
+++ /dev/null
@@ -1,250 +0,0 @@
1/* -*- linux-c -*- --------------------------------------------------------- *
2 *
3 * linux/fs/autofs/dirhash.c
4 *
5 * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
6 *
7 * This file is part of the Linux kernel and is made available under
8 * the terms of the GNU General Public License, version 2, or at your
9 * option, any later version, incorporated herein by reference.
10 *
11 * ------------------------------------------------------------------------- */
12
13#include "autofs_i.h"
14
15/* Functions for maintenance of expiry queue */
16
17static void autofs_init_usage(struct autofs_dirhash *dh,
18 struct autofs_dir_ent *ent)
19{
20 list_add_tail(&ent->exp, &dh->expiry_head);
21 ent->last_usage = jiffies;
22}
23
24static void autofs_delete_usage(struct autofs_dir_ent *ent)
25{
26 list_del(&ent->exp);
27}
28
29void autofs_update_usage(struct autofs_dirhash *dh,
30 struct autofs_dir_ent *ent)
31{
32 autofs_delete_usage(ent); /* Unlink from current position */
33 autofs_init_usage(dh,ent); /* Relink at queue tail */
34}
35
36struct autofs_dir_ent *autofs_expire(struct super_block *sb,
37 struct autofs_sb_info *sbi,
38 struct vfsmount *mnt)
39{
40 struct autofs_dirhash *dh = &sbi->dirhash;
41 struct autofs_dir_ent *ent;
42 unsigned long timeout = sbi->exp_timeout;
43
44 while (1) {
45 struct path path;
46 int umount_ok;
47
48 if ( list_empty(&dh->expiry_head) || sbi->catatonic )
49 return NULL; /* No entries */
50 /* We keep the list sorted by last_usage and want old stuff */
51 ent = list_entry(dh->expiry_head.next, struct autofs_dir_ent, exp);
52 if (jiffies - ent->last_usage < timeout)
53 break;
54 /* Move to end of list in case expiry isn't desirable */
55 autofs_update_usage(dh, ent);
56
57 /* Check to see that entry is expirable */
58 if ( ent->ino < AUTOFS_FIRST_DIR_INO )
59 return ent; /* Symlinks are always expirable */
60
61 /* Get the dentry for the autofs subdirectory */
62 path.dentry = ent->dentry;
63
64 if (!path.dentry) {
65 /* Should only happen in catatonic mode */
66 printk("autofs: dentry == NULL but inode range is directory, entry %s\n", ent->name);
67 autofs_delete_usage(ent);
68 continue;
69 }
70
71 if (!path.dentry->d_inode) {
72 dput(path.dentry);
73 printk("autofs: negative dentry on expiry queue: %s\n",
74 ent->name);
75 autofs_delete_usage(ent);
76 continue;
77 }
78
79 /* Make sure entry is mounted and unused; note that dentry will
80 point to the mounted-on-top root. */
81 if (!S_ISDIR(path.dentry->d_inode->i_mode) ||
82 !d_mountpoint(path.dentry)) {
83 DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name));
84 continue;
85 }
86 path.mnt = mnt;
87 path_get(&path);
88 if (!follow_down(&path)) {
89 path_put(&path);
90 DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name));
91 continue;
92 }
93 while (d_mountpoint(path.dentry) && follow_down(&path))
94 ;
95 umount_ok = may_umount(path.mnt);
96 path_put(&path);
97
98 if (umount_ok) {
99 DPRINTK(("autofs: signaling expire on %s\n", ent->name));
100 return ent; /* Expirable! */
101 }
102 DPRINTK(("autofs: didn't expire due to may_umount: %s\n", ent->name));
103 }
104 return NULL; /* No expirable entries */
105}
106
107void autofs_initialize_hash(struct autofs_dirhash *dh) {
108 memset(&dh->h, 0, AUTOFS_HASH_SIZE*sizeof(struct autofs_dir_ent *));
109 INIT_LIST_HEAD(&dh->expiry_head);
110}
111
112struct autofs_dir_ent *autofs_hash_lookup(const struct autofs_dirhash *dh, struct qstr *name)
113{
114 struct autofs_dir_ent *dhn;
115
116 DPRINTK(("autofs_hash_lookup: hash = 0x%08x, name = ", name->hash));
117 autofs_say(name->name,name->len);
118
119 for ( dhn = dh->h[(unsigned) name->hash % AUTOFS_HASH_SIZE] ; dhn ; dhn = dhn->next ) {
120 if ( name->hash == dhn->hash &&
121 name->len == dhn->len &&
122 !memcmp(name->name, dhn->name, name->len) )
123 break;
124 }
125
126 return dhn;
127}
128
129void autofs_hash_insert(struct autofs_dirhash *dh, struct autofs_dir_ent *ent)
130{
131 struct autofs_dir_ent **dhnp;
132
133 DPRINTK(("autofs_hash_insert: hash = 0x%08x, name = ", ent->hash));
134 autofs_say(ent->name,ent->len);
135
136 autofs_init_usage(dh,ent);
137 if (ent->dentry)
138 dget(ent->dentry);
139
140 dhnp = &dh->h[(unsigned) ent->hash % AUTOFS_HASH_SIZE];
141 ent->next = *dhnp;
142 ent->back = dhnp;
143 *dhnp = ent;
144 if ( ent->next )
145 ent->next->back = &(ent->next);
146}
147
148void autofs_hash_delete(struct autofs_dir_ent *ent)
149{
150 *(ent->back) = ent->next;
151 if ( ent->next )
152 ent->next->back = ent->back;
153
154 autofs_delete_usage(ent);
155
156 if ( ent->dentry )
157 dput(ent->dentry);
158 kfree(ent->name);
159 kfree(ent);
160}
161
162/*
163 * Used by readdir(). We must validate "ptr", so we can't simply make it
164 * a pointer. Values below 0xffff are reserved; calling with any value
165 * <= 0x10000 will return the first entry found.
166 *
167 * "last" can be NULL or the value returned by the last search *if* we
168 * want the next sequential entry.
169 */
170struct autofs_dir_ent *autofs_hash_enum(const struct autofs_dirhash *dh,
171 off_t *ptr, struct autofs_dir_ent *last)
172{
173 int bucket, ecount, i;
174 struct autofs_dir_ent *ent;
175
176 bucket = (*ptr >> 16) - 1;
177 ecount = *ptr & 0xffff;
178
179 if ( bucket < 0 ) {
180 bucket = ecount = 0;
181 }
182
183 DPRINTK(("autofs_hash_enum: bucket %d, entry %d\n", bucket, ecount));
184
185 ent = last ? last->next : NULL;
186
187 if ( ent ) {
188 ecount++;
189 } else {
190 while ( bucket < AUTOFS_HASH_SIZE ) {
191 ent = dh->h[bucket];
192 for ( i = ecount ; ent && i ; i-- )
193 ent = ent->next;
194
195 if (ent) {
196 ecount++; /* Point to *next* entry */
197 break;
198 }
199
200 bucket++; ecount = 0;
201 }
202 }
203
204#ifdef DEBUG
205 if ( !ent )
206 printk("autofs_hash_enum: nothing found\n");
207 else {
208 printk("autofs_hash_enum: found hash %08x, name", ent->hash);
209 autofs_say(ent->name,ent->len);
210 }
211#endif
212
213 *ptr = ((bucket+1) << 16) + ecount;
214 return ent;
215}
216
217/* Iterate over all the ents, and remove all dentry pointers. Used on
218 entering catatonic mode, in order to make the filesystem unmountable. */
219void autofs_hash_dputall(struct autofs_dirhash *dh)
220{
221 int i;
222 struct autofs_dir_ent *ent;
223
224 for ( i = 0 ; i < AUTOFS_HASH_SIZE ; i++ ) {
225 for ( ent = dh->h[i] ; ent ; ent = ent->next ) {
226 if ( ent->dentry ) {
227 dput(ent->dentry);
228 ent->dentry = NULL;
229 }
230 }
231 }
232}
233
234/* Delete everything. This is used on filesystem destruction, so we
235 make no attempt to keep the pointers valid */
236void autofs_hash_nuke(struct autofs_sb_info *sbi)
237{
238 int i;
239 struct autofs_dir_ent *ent, *nent;
240
241 for ( i = 0 ; i < AUTOFS_HASH_SIZE ; i++ ) {
242 for ( ent = sbi->dirhash.h[i] ; ent ; ent = nent ) {
243 nent = ent->next;
244 if ( ent->dentry )
245 dput(ent->dentry);
246 kfree(ent->name);
247 kfree(ent);
248 }
249 }
250}
diff --git a/fs/autofs/init.c b/fs/autofs/init.c
deleted file mode 100644
index cea5219b4f37..000000000000
--- a/fs/autofs/init.c
+++ /dev/null
@@ -1,52 +0,0 @@
1/* -*- linux-c -*- --------------------------------------------------------- *
2 *
3 * linux/fs/autofs/init.c
4 *
5 * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
6 *
7 * This file is part of the Linux kernel and is made available under
8 * the terms of the GNU General Public License, version 2, or at your
9 * option, any later version, incorporated herein by reference.
10 *
11 * ------------------------------------------------------------------------- */
12
13#include <linux/module.h>
14#include <linux/init.h>
15#include "autofs_i.h"
16
17static int autofs_get_sb(struct file_system_type *fs_type,
18 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
19{
20 return get_sb_nodev(fs_type, flags, data, autofs_fill_super, mnt);
21}
22
23static struct file_system_type autofs_fs_type = {
24 .owner = THIS_MODULE,
25 .name = "autofs",
26 .get_sb = autofs_get_sb,
27 .kill_sb = autofs_kill_sb,
28};
29
30static int __init init_autofs_fs(void)
31{
32 return register_filesystem(&autofs_fs_type);
33}
34
35static void __exit exit_autofs_fs(void)
36{
37 unregister_filesystem(&autofs_fs_type);
38}
39
40module_init(init_autofs_fs);
41module_exit(exit_autofs_fs);
42
43#ifdef DEBUG
44void autofs_say(const char *name, int len)
45{
46 printk("(%d: ", len);
47 while ( len-- )
48 printk("%c", *name++);
49 printk(")\n");
50}
51#endif
52MODULE_LICENSE("GPL");
diff --git a/fs/autofs/inode.c b/fs/autofs/inode.c
deleted file mode 100644
index e1734f2d6e26..000000000000
--- a/fs/autofs/inode.c
+++ /dev/null
@@ -1,288 +0,0 @@
1/* -*- linux-c -*- --------------------------------------------------------- *
2 *
3 * linux/fs/autofs/inode.c
4 *
5 * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
6 *
7 * This file is part of the Linux kernel and is made available under
8 * the terms of the GNU General Public License, version 2, or at your
9 * option, any later version, incorporated herein by reference.
10 *
11 * ------------------------------------------------------------------------- */
12
13#include <linux/kernel.h>
14#include <linux/mm.h>
15#include <linux/slab.h>
16#include <linux/file.h>
17#include <linux/parser.h>
18#include <linux/bitops.h>
19#include <linux/magic.h>
20#include "autofs_i.h"
21#include <linux/module.h>
22
23void autofs_kill_sb(struct super_block *sb)
24{
25 struct autofs_sb_info *sbi = autofs_sbi(sb);
26 unsigned int n;
27
28 /*
29 * In the event of a failure in get_sb_nodev the superblock
30 * info is not present so nothing else has been setup, so
31 * just call kill_anon_super when we are called from
32 * deactivate_super.
33 */
34 if (!sbi)
35 goto out_kill_sb;
36
37 if (!sbi->catatonic)
38 autofs_catatonic_mode(sbi); /* Free wait queues, close pipe */
39
40 put_pid(sbi->oz_pgrp);
41
42 autofs_hash_nuke(sbi);
43 for (n = 0; n < AUTOFS_MAX_SYMLINKS; n++) {
44 if (test_bit(n, sbi->symlink_bitmap))
45 kfree(sbi->symlink[n].data);
46 }
47
48 kfree(sb->s_fs_info);
49
50out_kill_sb:
51 DPRINTK(("autofs: shutting down\n"));
52 kill_anon_super(sb);
53}
54
55static const struct super_operations autofs_sops = {
56 .statfs = simple_statfs,
57 .show_options = generic_show_options,
58};
59
60enum {Opt_err, Opt_fd, Opt_uid, Opt_gid, Opt_pgrp, Opt_minproto, Opt_maxproto};
61
62static const match_table_t autofs_tokens = {
63 {Opt_fd, "fd=%u"},
64 {Opt_uid, "uid=%u"},
65 {Opt_gid, "gid=%u"},
66 {Opt_pgrp, "pgrp=%u"},
67 {Opt_minproto, "minproto=%u"},
68 {Opt_maxproto, "maxproto=%u"},
69 {Opt_err, NULL}
70};
71
72static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
73 pid_t *pgrp, int *minproto, int *maxproto)
74{
75 char *p;
76 substring_t args[MAX_OPT_ARGS];
77 int option;
78
79 *uid = current_uid();
80 *gid = current_gid();
81 *pgrp = task_pgrp_nr(current);
82
83 *minproto = *maxproto = AUTOFS_PROTO_VERSION;
84
85 *pipefd = -1;
86
87 if (!options)
88 return 1;
89
90 while ((p = strsep(&options, ",")) != NULL) {
91 int token;
92 if (!*p)
93 continue;
94
95 token = match_token(p, autofs_tokens, args);
96 switch (token) {
97 case Opt_fd:
98 if (match_int(&args[0], &option))
99 return 1;
100 *pipefd = option;
101 break;
102 case Opt_uid:
103 if (match_int(&args[0], &option))
104 return 1;
105 *uid = option;
106 break;
107 case Opt_gid:
108 if (match_int(&args[0], &option))
109 return 1;
110 *gid = option;
111 break;
112 case Opt_pgrp:
113 if (match_int(&args[0], &option))
114 return 1;
115 *pgrp = option;
116 break;
117 case Opt_minproto:
118 if (match_int(&args[0], &option))
119 return 1;
120 *minproto = option;
121 break;
122 case Opt_maxproto:
123 if (match_int(&args[0], &option))
124 return 1;
125 *maxproto = option;
126 break;
127 default:
128 return 1;
129 }
130 }
131 return (*pipefd < 0);
132}
133
134int autofs_fill_super(struct super_block *s, void *data, int silent)
135{
136 struct inode * root_inode;
137 struct dentry * root;
138 struct file * pipe;
139 int pipefd;
140 struct autofs_sb_info *sbi;
141 int minproto, maxproto;
142 pid_t pgid;
143
144 save_mount_options(s, data);
145
146 sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
147 if (!sbi)
148 goto fail_unlock;
149 DPRINTK(("autofs: starting up, sbi = %p\n",sbi));
150
151 s->s_fs_info = sbi;
152 sbi->magic = AUTOFS_SBI_MAGIC;
153 sbi->pipe = NULL;
154 sbi->catatonic = 1;
155 sbi->exp_timeout = 0;
156 autofs_initialize_hash(&sbi->dirhash);
157 sbi->queues = NULL;
158 memset(sbi->symlink_bitmap, 0, sizeof(long)*AUTOFS_SYMLINK_BITMAP_LEN);
159 sbi->next_dir_ino = AUTOFS_FIRST_DIR_INO;
160 s->s_blocksize = 1024;
161 s->s_blocksize_bits = 10;
162 s->s_magic = AUTOFS_SUPER_MAGIC;
163 s->s_op = &autofs_sops;
164 s->s_time_gran = 1;
165 sbi->sb = s;
166
167 root_inode = autofs_iget(s, AUTOFS_ROOT_INO);
168 if (IS_ERR(root_inode))
169 goto fail_free;
170 root = d_alloc_root(root_inode);
171 pipe = NULL;
172
173 if (!root)
174 goto fail_iput;
175
176 /* Can this call block? - WTF cares? s is locked. */
177 if (parse_options(data, &pipefd, &root_inode->i_uid,
178 &root_inode->i_gid, &pgid, &minproto,
179 &maxproto)) {
180 printk("autofs: called with bogus options\n");
181 goto fail_dput;
182 }
183
184 /* Couldn't this be tested earlier? */
185 if (minproto > AUTOFS_PROTO_VERSION ||
186 maxproto < AUTOFS_PROTO_VERSION) {
187 printk("autofs: kernel does not match daemon version\n");
188 goto fail_dput;
189 }
190
191 DPRINTK(("autofs: pipe fd = %d, pgrp = %u\n", pipefd, pgid));
192 sbi->oz_pgrp = find_get_pid(pgid);
193
194 if (!sbi->oz_pgrp) {
195 printk("autofs: could not find process group %d\n", pgid);
196 goto fail_dput;
197 }
198
199 pipe = fget(pipefd);
200
201 if (!pipe) {
202 printk("autofs: could not open pipe file descriptor\n");
203 goto fail_put_pid;
204 }
205
206 if (!pipe->f_op || !pipe->f_op->write)
207 goto fail_fput;
208 sbi->pipe = pipe;
209 sbi->catatonic = 0;
210
211 /*
212 * Success! Install the root dentry now to indicate completion.
213 */
214 s->s_root = root;
215 return 0;
216
217fail_fput:
218 printk("autofs: pipe file descriptor does not contain proper ops\n");
219 fput(pipe);
220fail_put_pid:
221 put_pid(sbi->oz_pgrp);
222fail_dput:
223 dput(root);
224 goto fail_free;
225fail_iput:
226 printk("autofs: get root dentry failed\n");
227 iput(root_inode);
228fail_free:
229 kfree(sbi);
230 s->s_fs_info = NULL;
231fail_unlock:
232 return -EINVAL;
233}
234
235struct inode *autofs_iget(struct super_block *sb, unsigned long ino)
236{
237 unsigned int n;
238 struct autofs_sb_info *sbi = autofs_sbi(sb);
239 struct inode *inode;
240
241 inode = iget_locked(sb, ino);
242 if (!inode)
243 return ERR_PTR(-ENOMEM);
244 if (!(inode->i_state & I_NEW))
245 return inode;
246
247 /* Initialize to the default case (stub directory) */
248
249 inode->i_op = &simple_dir_inode_operations;
250 inode->i_fop = &simple_dir_operations;
251 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
252 inode->i_nlink = 2;
253 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
254
255 if (ino == AUTOFS_ROOT_INO) {
256 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
257 inode->i_op = &autofs_root_inode_operations;
258 inode->i_fop = &autofs_root_operations;
259 goto done;
260 }
261
262 inode->i_uid = inode->i_sb->s_root->d_inode->i_uid;
263 inode->i_gid = inode->i_sb->s_root->d_inode->i_gid;
264
265 if (ino >= AUTOFS_FIRST_SYMLINK && ino < AUTOFS_FIRST_DIR_INO) {
266 /* Symlink inode - should be in symlink list */
267 struct autofs_symlink *sl;
268
269 n = ino - AUTOFS_FIRST_SYMLINK;
270 if (n >= AUTOFS_MAX_SYMLINKS || !test_bit(n,sbi->symlink_bitmap)) {
271 printk("autofs: Looking for bad symlink inode %u\n", (unsigned int) ino);
272 goto done;
273 }
274
275 inode->i_op = &autofs_symlink_inode_operations;
276 sl = &sbi->symlink[n];
277 inode->i_private = sl;
278 inode->i_mode = S_IFLNK | S_IRWXUGO;
279 inode->i_mtime.tv_sec = inode->i_ctime.tv_sec = sl->mtime;
280 inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = 0;
281 inode->i_size = sl->len;
282 inode->i_nlink = 1;
283 }
284
285done:
286 unlock_new_inode(inode);
287 return inode;
288}
diff --git a/fs/autofs/root.c b/fs/autofs/root.c
deleted file mode 100644
index 11b1ea786d00..000000000000
--- a/fs/autofs/root.c
+++ /dev/null
@@ -1,643 +0,0 @@
1/* -*- linux-c -*- --------------------------------------------------------- *
2 *
3 * linux/fs/autofs/root.c
4 *
5 * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
6 *
7 * This file is part of the Linux kernel and is made available under
8 * the terms of the GNU General Public License, version 2, or at your
9 * option, any later version, incorporated herein by reference.
10 *
11 * ------------------------------------------------------------------------- */
12
13#include <linux/capability.h>
14#include <linux/errno.h>
15#include <linux/stat.h>
16#include <linux/slab.h>
17#include <linux/param.h>
18#include <linux/time.h>
19#include <linux/compat.h>
20#include <linux/smp_lock.h>
21#include "autofs_i.h"
22
23static int autofs_root_readdir(struct file *,void *,filldir_t);
24static struct dentry *autofs_root_lookup(struct inode *,struct dentry *, struct nameidata *);
25static int autofs_root_symlink(struct inode *,struct dentry *,const char *);
26static int autofs_root_unlink(struct inode *,struct dentry *);
27static int autofs_root_rmdir(struct inode *,struct dentry *);
28static int autofs_root_mkdir(struct inode *,struct dentry *,int);
29static long autofs_root_ioctl(struct file *,unsigned int,unsigned long);
30static long autofs_root_compat_ioctl(struct file *,unsigned int,unsigned long);
31
32const struct file_operations autofs_root_operations = {
33 .llseek = generic_file_llseek,
34 .read = generic_read_dir,
35 .readdir = autofs_root_readdir,
36 .unlocked_ioctl = autofs_root_ioctl,
37#ifdef CONFIG_COMPAT
38 .compat_ioctl = autofs_root_compat_ioctl,
39#endif
40};
41
42const struct inode_operations autofs_root_inode_operations = {
43 .lookup = autofs_root_lookup,
44 .unlink = autofs_root_unlink,
45 .symlink = autofs_root_symlink,
46 .mkdir = autofs_root_mkdir,
47 .rmdir = autofs_root_rmdir,
48};
49
50static int autofs_root_readdir(struct file *filp, void *dirent, filldir_t filldir)
51{
52 struct autofs_dir_ent *ent = NULL;
53 struct autofs_dirhash *dirhash;
54 struct autofs_sb_info *sbi;
55 struct inode * inode = filp->f_path.dentry->d_inode;
56 off_t onr, nr;
57
58 lock_kernel();
59
60 sbi = autofs_sbi(inode->i_sb);
61 dirhash = &sbi->dirhash;
62 nr = filp->f_pos;
63
64 switch(nr)
65 {
66 case 0:
67 if (filldir(dirent, ".", 1, nr, inode->i_ino, DT_DIR) < 0)
68 goto out;
69 filp->f_pos = ++nr;
70 /* fall through */
71 case 1:
72 if (filldir(dirent, "..", 2, nr, inode->i_ino, DT_DIR) < 0)
73 goto out;
74 filp->f_pos = ++nr;
75 /* fall through */
76 default:
77 while (onr = nr, ent = autofs_hash_enum(dirhash,&nr,ent)) {
78 if (!ent->dentry || d_mountpoint(ent->dentry)) {
79 if (filldir(dirent,ent->name,ent->len,onr,ent->ino,DT_UNKNOWN) < 0)
80 goto out;
81 filp->f_pos = nr;
82 }
83 }
84 break;
85 }
86
87out:
88 unlock_kernel();
89 return 0;
90}
91
92static int try_to_fill_dentry(struct dentry *dentry, struct super_block *sb, struct autofs_sb_info *sbi)
93{
94 struct inode * inode;
95 struct autofs_dir_ent *ent;
96 int status = 0;
97
98 if (!(ent = autofs_hash_lookup(&sbi->dirhash, &dentry->d_name))) {
99 do {
100 if (status && dentry->d_inode) {
101 if (status != -ENOENT)
102 printk("autofs warning: lookup failure on positive dentry, status = %d, name = %s\n", status, dentry->d_name.name);
103 return 0; /* Try to get the kernel to invalidate this dentry */
104 }
105
106 /* Turn this into a real negative dentry? */
107 if (status == -ENOENT) {
108 dentry->d_time = jiffies + AUTOFS_NEGATIVE_TIMEOUT;
109 dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
110 return 1;
111 } else if (status) {
112 /* Return a negative dentry, but leave it "pending" */
113 return 1;
114 }
115 status = autofs_wait(sbi, &dentry->d_name);
116 } while (!(ent = autofs_hash_lookup(&sbi->dirhash, &dentry->d_name)));
117 }
118
119 /* Abuse this field as a pointer to the directory entry, used to
120 find the expire list pointers */
121 dentry->d_time = (unsigned long) ent;
122
123 if (!dentry->d_inode) {
124 inode = autofs_iget(sb, ent->ino);
125 if (IS_ERR(inode)) {
126 /* Failed, but leave pending for next time */
127 return 1;
128 }
129 dentry->d_inode = inode;
130 }
131
132 /* If this is a directory that isn't a mount point, bitch at the
133 daemon and fix it in user space */
134 if (S_ISDIR(dentry->d_inode->i_mode) && !d_mountpoint(dentry)) {
135 return !autofs_wait(sbi, &dentry->d_name);
136 }
137
138 /* We don't update the usages for the autofs daemon itself, this
139 is necessary for recursive autofs mounts */
140 if (!autofs_oz_mode(sbi)) {
141 autofs_update_usage(&sbi->dirhash,ent);
142 }
143
144 dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
145 return 1;
146}
147
148
149/*
150 * Revalidate is called on every cache lookup. Some of those
151 * cache lookups may actually happen while the dentry is not
152 * yet completely filled in, and revalidate has to delay such
153 * lookups..
154 */
155static int autofs_revalidate(struct dentry * dentry, struct nameidata *nd)
156{
157 struct inode * dir;
158 struct autofs_sb_info *sbi;
159 struct autofs_dir_ent *ent;
160 int res;
161
162 lock_kernel();
163 dir = dentry->d_parent->d_inode;
164 sbi = autofs_sbi(dir->i_sb);
165
166 /* Pending dentry */
167 if (dentry->d_flags & DCACHE_AUTOFS_PENDING) {
168 if (autofs_oz_mode(sbi))
169 res = 1;
170 else
171 res = try_to_fill_dentry(dentry, dir->i_sb, sbi);
172 unlock_kernel();
173 return res;
174 }
175
176 /* Negative dentry.. invalidate if "old" */
177 if (!dentry->d_inode) {
178 unlock_kernel();
179 return (dentry->d_time - jiffies <= AUTOFS_NEGATIVE_TIMEOUT);
180 }
181
182 /* Check for a non-mountpoint directory */
183 if (S_ISDIR(dentry->d_inode->i_mode) && !d_mountpoint(dentry)) {
184 if (autofs_oz_mode(sbi))
185 res = 1;
186 else
187 res = try_to_fill_dentry(dentry, dir->i_sb, sbi);
188 unlock_kernel();
189 return res;
190 }
191
192 /* Update the usage list */
193 if (!autofs_oz_mode(sbi)) {
194 ent = (struct autofs_dir_ent *) dentry->d_time;
195 if (ent)
196 autofs_update_usage(&sbi->dirhash,ent);
197 }
198 unlock_kernel();
199 return 1;
200}
201
202static const struct dentry_operations autofs_dentry_operations = {
203 .d_revalidate = autofs_revalidate,
204};
205
206static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
207{
208 struct autofs_sb_info *sbi;
209 int oz_mode;
210
211 DPRINTK(("autofs_root_lookup: name = "));
212 lock_kernel();
213 autofs_say(dentry->d_name.name,dentry->d_name.len);
214
215 if (dentry->d_name.len > NAME_MAX) {
216 unlock_kernel();
217 return ERR_PTR(-ENAMETOOLONG);/* File name too long to exist */
218 }
219
220 sbi = autofs_sbi(dir->i_sb);
221
222 oz_mode = autofs_oz_mode(sbi);
223 DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, "
224 "oz_mode = %d\n", task_pid_nr(current),
225 task_pgrp_nr(current), sbi->catatonic,
226 oz_mode));
227
228 /*
229 * Mark the dentry incomplete, but add it. This is needed so
230 * that the VFS layer knows about the dentry, and we can count
231 * on catching any lookups through the revalidate.
232 *
233 * Let all the hard work be done by the revalidate function that
234 * needs to be able to do this anyway..
235 *
236 * We need to do this before we release the directory semaphore.
237 */
238 dentry->d_op = &autofs_dentry_operations;
239 dentry->d_flags |= DCACHE_AUTOFS_PENDING;
240 d_add(dentry, NULL);
241
242 mutex_unlock(&dir->i_mutex);
243 autofs_revalidate(dentry, nd);
244 mutex_lock(&dir->i_mutex);
245
246 /*
247 * If we are still pending, check if we had to handle
248 * a signal. If so we can force a restart..
249 */
250 if (dentry->d_flags & DCACHE_AUTOFS_PENDING) {
251 /* See if we were interrupted */
252 if (signal_pending(current)) {
253 sigset_t *sigset = &current->pending.signal;
254 if (sigismember (sigset, SIGKILL) ||
255 sigismember (sigset, SIGQUIT) ||
256 sigismember (sigset, SIGINT)) {
257 unlock_kernel();
258 return ERR_PTR(-ERESTARTNOINTR);
259 }
260 }
261 }
262 unlock_kernel();
263
264 /*
265 * If this dentry is unhashed, then we shouldn't honour this
266 * lookup even if the dentry is positive. Returning ENOENT here
267 * doesn't do the right thing for all system calls, but it should
268 * be OK for the operations we permit from an autofs.
269 */
270 if (dentry->d_inode && d_unhashed(dentry))
271 return ERR_PTR(-ENOENT);
272
273 return NULL;
274}
275
276static int autofs_root_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
277{
278 struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb);
279 struct autofs_dirhash *dh = &sbi->dirhash;
280 struct autofs_dir_ent *ent;
281 unsigned int n;
282 int slsize;
283 struct autofs_symlink *sl;
284 struct inode *inode;
285
286 DPRINTK(("autofs_root_symlink: %s <- ", symname));
287 autofs_say(dentry->d_name.name,dentry->d_name.len);
288
289 lock_kernel();
290 if (!autofs_oz_mode(sbi)) {
291 unlock_kernel();
292 return -EACCES;
293 }
294
295 if (autofs_hash_lookup(dh, &dentry->d_name)) {
296 unlock_kernel();
297 return -EEXIST;
298 }
299
300 n = find_first_zero_bit(sbi->symlink_bitmap,AUTOFS_MAX_SYMLINKS);
301 if (n >= AUTOFS_MAX_SYMLINKS) {
302 unlock_kernel();
303 return -ENOSPC;
304 }
305
306 set_bit(n,sbi->symlink_bitmap);
307 sl = &sbi->symlink[n];
308 sl->len = strlen(symname);
309 sl->data = kmalloc(slsize = sl->len+1, GFP_KERNEL);
310 if (!sl->data) {
311 clear_bit(n,sbi->symlink_bitmap);
312 unlock_kernel();
313 return -ENOSPC;
314 }
315
316 ent = kmalloc(sizeof(struct autofs_dir_ent), GFP_KERNEL);
317 if (!ent) {
318 kfree(sl->data);
319 clear_bit(n,sbi->symlink_bitmap);
320 unlock_kernel();
321 return -ENOSPC;
322 }
323
324 ent->name = kmalloc(dentry->d_name.len+1, GFP_KERNEL);
325 if (!ent->name) {
326 kfree(sl->data);
327 kfree(ent);
328 clear_bit(n,sbi->symlink_bitmap);
329 unlock_kernel();
330 return -ENOSPC;
331 }
332
333 memcpy(sl->data,symname,slsize);
334 sl->mtime = get_seconds();
335
336 ent->ino = AUTOFS_FIRST_SYMLINK + n;
337 ent->hash = dentry->d_name.hash;
338 memcpy(ent->name, dentry->d_name.name, 1+(ent->len = dentry->d_name.len));
339 ent->dentry = NULL; /* We don't keep the dentry for symlinks */
340
341 autofs_hash_insert(dh,ent);
342
343 inode = autofs_iget(dir->i_sb, ent->ino);
344 if (IS_ERR(inode))
345 return PTR_ERR(inode);
346
347 d_instantiate(dentry, inode);
348 unlock_kernel();
349 return 0;
350}
351
352/*
353 * NOTE!
354 *
355 * Normal filesystems would do a "d_delete()" to tell the VFS dcache
356 * that the file no longer exists. However, doing that means that the
357 * VFS layer can turn the dentry into a negative dentry, which we
358 * obviously do not want (we're dropping the entry not because it
359 * doesn't exist, but because it has timed out).
360 *
361 * Also see autofs_root_rmdir()..
362 */
363static int autofs_root_unlink(struct inode *dir, struct dentry *dentry)
364{
365 struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb);
366 struct autofs_dirhash *dh = &sbi->dirhash;
367 struct autofs_dir_ent *ent;
368 unsigned int n;
369
370 /* This allows root to remove symlinks */
371 lock_kernel();
372 if (!autofs_oz_mode(sbi) && !capable(CAP_SYS_ADMIN)) {
373 unlock_kernel();
374 return -EACCES;
375 }
376
377 ent = autofs_hash_lookup(dh, &dentry->d_name);
378 if (!ent) {
379 unlock_kernel();
380 return -ENOENT;
381 }
382
383 n = ent->ino - AUTOFS_FIRST_SYMLINK;
384 if (n >= AUTOFS_MAX_SYMLINKS) {
385 unlock_kernel();
386 return -EISDIR; /* It's a directory, dummy */
387 }
388 if (!test_bit(n,sbi->symlink_bitmap)) {
389 unlock_kernel();
390 return -EINVAL; /* Nonexistent symlink? Shouldn't happen */
391 }
392
393 dentry->d_time = (unsigned long)(struct autofs_dirhash *)NULL;
394 autofs_hash_delete(ent);
395 clear_bit(n,sbi->symlink_bitmap);
396 kfree(sbi->symlink[n].data);
397 d_drop(dentry);
398
399 unlock_kernel();
400 return 0;
401}
402
403static int autofs_root_rmdir(struct inode *dir, struct dentry *dentry)
404{
405 struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb);
406 struct autofs_dirhash *dh = &sbi->dirhash;
407 struct autofs_dir_ent *ent;
408
409 lock_kernel();
410 if (!autofs_oz_mode(sbi)) {
411 unlock_kernel();
412 return -EACCES;
413 }
414
415 ent = autofs_hash_lookup(dh, &dentry->d_name);
416 if (!ent) {
417 unlock_kernel();
418 return -ENOENT;
419 }
420
421 if ((unsigned int)ent->ino < AUTOFS_FIRST_DIR_INO) {
422 unlock_kernel();
423 return -ENOTDIR; /* Not a directory */
424 }
425
426 if (ent->dentry != dentry) {
427 printk("autofs_rmdir: odentry != dentry for entry %s\n", dentry->d_name.name);
428 }
429
430 dentry->d_time = (unsigned long)(struct autofs_dir_ent *)NULL;
431 autofs_hash_delete(ent);
432 drop_nlink(dir);
433 d_drop(dentry);
434 unlock_kernel();
435
436 return 0;
437}
438
439static int autofs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode)
440{
441 struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb);
442 struct autofs_dirhash *dh = &sbi->dirhash;
443 struct autofs_dir_ent *ent;
444 struct inode *inode;
445 ino_t ino;
446
447 lock_kernel();
448 if (!autofs_oz_mode(sbi)) {
449 unlock_kernel();
450 return -EACCES;
451 }
452
453 ent = autofs_hash_lookup(dh, &dentry->d_name);
454 if (ent) {
455 unlock_kernel();
456 return -EEXIST;
457 }
458
459 if (sbi->next_dir_ino < AUTOFS_FIRST_DIR_INO) {
460 printk("autofs: Out of inode numbers -- what the heck did you do??\n");
461 unlock_kernel();
462 return -ENOSPC;
463 }
464 ino = sbi->next_dir_ino++;
465
466 ent = kmalloc(sizeof(struct autofs_dir_ent), GFP_KERNEL);
467 if (!ent) {
468 unlock_kernel();
469 return -ENOSPC;
470 }
471
472 ent->name = kmalloc(dentry->d_name.len+1, GFP_KERNEL);
473 if (!ent->name) {
474 kfree(ent);
475 unlock_kernel();
476 return -ENOSPC;
477 }
478
479 ent->hash = dentry->d_name.hash;
480 memcpy(ent->name, dentry->d_name.name, 1+(ent->len = dentry->d_name.len));
481 ent->ino = ino;
482 ent->dentry = dentry;
483 autofs_hash_insert(dh,ent);
484
485 inc_nlink(dir);
486
487 inode = autofs_iget(dir->i_sb, ino);
488 if (IS_ERR(inode)) {
489 drop_nlink(dir);
490 return PTR_ERR(inode);
491 }
492
493 d_instantiate(dentry, inode);
494 unlock_kernel();
495
496 return 0;
497}
498
499/* Get/set timeout ioctl() operation */
500#ifdef CONFIG_COMPAT
501static inline int autofs_compat_get_set_timeout(struct autofs_sb_info *sbi,
502 unsigned int __user *p)
503{
504 unsigned long ntimeout;
505
506 if (get_user(ntimeout, p) ||
507 put_user(sbi->exp_timeout / HZ, p))
508 return -EFAULT;
509
510 if (ntimeout > UINT_MAX/HZ)
511 sbi->exp_timeout = 0;
512 else
513 sbi->exp_timeout = ntimeout * HZ;
514
515 return 0;
516}
517#endif
518
519static inline int autofs_get_set_timeout(struct autofs_sb_info *sbi,
520 unsigned long __user *p)
521{
522 unsigned long ntimeout;
523
524 if (get_user(ntimeout, p) ||
525 put_user(sbi->exp_timeout / HZ, p))
526 return -EFAULT;
527
528 if (ntimeout > ULONG_MAX/HZ)
529 sbi->exp_timeout = 0;
530 else
531 sbi->exp_timeout = ntimeout * HZ;
532
533 return 0;
534}
535
536/* Return protocol version */
537static inline int autofs_get_protover(int __user *p)
538{
539 return put_user(AUTOFS_PROTO_VERSION, p);
540}
541
542/* Perform an expiry operation */
543static inline int autofs_expire_run(struct super_block *sb,
544 struct autofs_sb_info *sbi,
545 struct vfsmount *mnt,
546 struct autofs_packet_expire __user *pkt_p)
547{
548 struct autofs_dir_ent *ent;
549 struct autofs_packet_expire pkt;
550
551 memset(&pkt,0,sizeof pkt);
552
553 pkt.hdr.proto_version = AUTOFS_PROTO_VERSION;
554 pkt.hdr.type = autofs_ptype_expire;
555
556 if (!sbi->exp_timeout || !(ent = autofs_expire(sb,sbi,mnt)))
557 return -EAGAIN;
558
559 pkt.len = ent->len;
560 memcpy(pkt.name, ent->name, pkt.len);
561 pkt.name[pkt.len] = '\0';
562
563 if (copy_to_user(pkt_p, &pkt, sizeof(struct autofs_packet_expire)))
564 return -EFAULT;
565
566 return 0;
567}
568
569/*
570 * ioctl()'s on the root directory is the chief method for the daemon to
571 * generate kernel reactions
572 */
573static int autofs_do_root_ioctl(struct inode *inode, struct file *filp,
574 unsigned int cmd, unsigned long arg)
575{
576 struct autofs_sb_info *sbi = autofs_sbi(inode->i_sb);
577 void __user *argp = (void __user *)arg;
578
579 DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",cmd,arg,sbi,task_pgrp_nr(current)));
580
581 if (_IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) ||
582 _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT)
583 return -ENOTTY;
584
585 if (!autofs_oz_mode(sbi) && !capable(CAP_SYS_ADMIN))
586 return -EPERM;
587
588 switch(cmd) {
589 case AUTOFS_IOC_READY: /* Wait queue: go ahead and retry */
590 return autofs_wait_release(sbi,(autofs_wqt_t)arg,0);
591 case AUTOFS_IOC_FAIL: /* Wait queue: fail with ENOENT */
592 return autofs_wait_release(sbi,(autofs_wqt_t)arg,-ENOENT);
593 case AUTOFS_IOC_CATATONIC: /* Enter catatonic mode (daemon shutdown) */
594 autofs_catatonic_mode(sbi);
595 return 0;
596 case AUTOFS_IOC_PROTOVER: /* Get protocol version */
597 return autofs_get_protover(argp);
598#ifdef CONFIG_COMPAT
599 case AUTOFS_IOC_SETTIMEOUT32:
600 return autofs_compat_get_set_timeout(sbi, argp);
601#endif
602 case AUTOFS_IOC_SETTIMEOUT:
603 return autofs_get_set_timeout(sbi, argp);
604 case AUTOFS_IOC_EXPIRE:
605 return autofs_expire_run(inode->i_sb, sbi, filp->f_path.mnt,
606 argp);
607 default:
608 return -ENOSYS;
609 }
610
611}
612
613static long autofs_root_ioctl(struct file *filp,
614 unsigned int cmd, unsigned long arg)
615{
616 int ret;
617
618 lock_kernel();
619 ret = autofs_do_root_ioctl(filp->f_path.dentry->d_inode,
620 filp, cmd, arg);
621 unlock_kernel();
622
623 return ret;
624}
625
626#ifdef CONFIG_COMPAT
627static long autofs_root_compat_ioctl(struct file *filp,
628 unsigned int cmd, unsigned long arg)
629{
630 struct inode *inode = filp->f_path.dentry->d_inode;
631 int ret;
632
633 lock_kernel();
634 if (cmd == AUTOFS_IOC_READY || cmd == AUTOFS_IOC_FAIL)
635 ret = autofs_do_root_ioctl(inode, filp, cmd, arg);
636 else
637 ret = autofs_do_root_ioctl(inode, filp, cmd,
638 (unsigned long)compat_ptr(arg));
639 unlock_kernel();
640
641 return ret;
642}
643#endif
diff --git a/fs/autofs/symlink.c b/fs/autofs/symlink.c
deleted file mode 100644
index 7ce9cb2c9ce2..000000000000
--- a/fs/autofs/symlink.c
+++ /dev/null
@@ -1,26 +0,0 @@
1/* -*- linux-c -*- --------------------------------------------------------- *
2 *
3 * linux/fs/autofs/symlink.c
4 *
5 * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
6 *
7 * This file is part of the Linux kernel and is made available under
8 * the terms of the GNU General Public License, version 2, or at your
9 * option, any later version, incorporated herein by reference.
10 *
11 * ------------------------------------------------------------------------- */
12
13#include "autofs_i.h"
14
15/* Nothing to release.. */
16static void *autofs_follow_link(struct dentry *dentry, struct nameidata *nd)
17{
18 char *s=((struct autofs_symlink *)dentry->d_inode->i_private)->data;
19 nd_set_link(nd, s);
20 return NULL;
21}
22
23const struct inode_operations autofs_symlink_inode_operations = {
24 .readlink = generic_readlink,
25 .follow_link = autofs_follow_link
26};
diff --git a/fs/autofs/waitq.c b/fs/autofs/waitq.c
deleted file mode 100644
index be46805972f0..000000000000
--- a/fs/autofs/waitq.c
+++ /dev/null
@@ -1,205 +0,0 @@
1/* -*- linux-c -*- --------------------------------------------------------- *
2 *
3 * linux/fs/autofs/waitq.c
4 *
5 * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
6 *
7 * This file is part of the Linux kernel and is made available under
8 * the terms of the GNU General Public License, version 2, or at your
9 * option, any later version, incorporated herein by reference.
10 *
11 * ------------------------------------------------------------------------- */
12
13#include <linux/slab.h>
14#include <linux/time.h>
15#include <linux/signal.h>
16#include <linux/file.h>
17#include "autofs_i.h"
18
19/* We make this a static variable rather than a part of the superblock; it
20 is better if we don't reassign numbers easily even across filesystems */
21static autofs_wqt_t autofs_next_wait_queue = 1;
22
23/* These are the signals we allow interrupting a pending mount */
24#define SHUTDOWN_SIGS (sigmask(SIGKILL) | sigmask(SIGINT) | sigmask(SIGQUIT))
25
26void autofs_catatonic_mode(struct autofs_sb_info *sbi)
27{
28 struct autofs_wait_queue *wq, *nwq;
29
30 DPRINTK(("autofs: entering catatonic mode\n"));
31
32 sbi->catatonic = 1;
33 wq = sbi->queues;
34 sbi->queues = NULL; /* Erase all wait queues */
35 while ( wq ) {
36 nwq = wq->next;
37 wq->status = -ENOENT; /* Magic is gone - report failure */
38 kfree(wq->name);
39 wq->name = NULL;
40 wake_up(&wq->queue);
41 wq = nwq;
42 }
43 fput(sbi->pipe); /* Close the pipe */
44 sbi->pipe = NULL;
45 autofs_hash_dputall(&sbi->dirhash); /* Remove all dentry pointers */
46}
47
48static int autofs_write(struct file *file, const void *addr, int bytes)
49{
50 unsigned long sigpipe, flags;
51 mm_segment_t fs;
52 const char *data = (const char *)addr;
53 ssize_t wr = 0;
54
55 /** WARNING: this is not safe for writing more than PIPE_BUF bytes! **/
56
57 sigpipe = sigismember(&current->pending.signal, SIGPIPE);
58
59 /* Save pointer to user space and point back to kernel space */
60 fs = get_fs();
61 set_fs(KERNEL_DS);
62
63 while (bytes &&
64 (wr = file->f_op->write(file,data,bytes,&file->f_pos)) > 0) {
65 data += wr;
66 bytes -= wr;
67 }
68
69 set_fs(fs);
70
71 /* Keep the currently executing process from receiving a
72 SIGPIPE unless it was already supposed to get one */
73 if (wr == -EPIPE && !sigpipe) {
74 spin_lock_irqsave(&current->sighand->siglock, flags);
75 sigdelset(&current->pending.signal, SIGPIPE);
76 recalc_sigpending();
77 spin_unlock_irqrestore(&current->sighand->siglock, flags);
78 }
79
80 return (bytes > 0);
81}
82
83static void autofs_notify_daemon(struct autofs_sb_info *sbi, struct autofs_wait_queue *wq)
84{
85 struct autofs_packet_missing pkt;
86
87 DPRINTK(("autofs_wait: wait id = 0x%08lx, name = ", wq->wait_queue_token));
88 autofs_say(wq->name,wq->len);
89
90 memset(&pkt,0,sizeof pkt); /* For security reasons */
91
92 pkt.hdr.proto_version = AUTOFS_PROTO_VERSION;
93 pkt.hdr.type = autofs_ptype_missing;
94 pkt.wait_queue_token = wq->wait_queue_token;
95 pkt.len = wq->len;
96 memcpy(pkt.name, wq->name, pkt.len);
97 pkt.name[pkt.len] = '\0';
98
99 if ( autofs_write(sbi->pipe,&pkt,sizeof(struct autofs_packet_missing)) )
100 autofs_catatonic_mode(sbi);
101}
102
103int autofs_wait(struct autofs_sb_info *sbi, struct qstr *name)
104{
105 struct autofs_wait_queue *wq;
106 int status;
107
108 /* In catatonic mode, we don't wait for nobody */
109 if ( sbi->catatonic )
110 return -ENOENT;
111
112 /* We shouldn't be able to get here, but just in case */
113 if ( name->len > NAME_MAX )
114 return -ENOENT;
115
116 for ( wq = sbi->queues ; wq ; wq = wq->next ) {
117 if ( wq->hash == name->hash &&
118 wq->len == name->len &&
119 wq->name && !memcmp(wq->name,name->name,name->len) )
120 break;
121 }
122
123 if ( !wq ) {
124 /* Create a new wait queue */
125 wq = kmalloc(sizeof(struct autofs_wait_queue),GFP_KERNEL);
126 if ( !wq )
127 return -ENOMEM;
128
129 wq->name = kmalloc(name->len,GFP_KERNEL);
130 if ( !wq->name ) {
131 kfree(wq);
132 return -ENOMEM;
133 }
134 wq->wait_queue_token = autofs_next_wait_queue++;
135 init_waitqueue_head(&wq->queue);
136 wq->hash = name->hash;
137 wq->len = name->len;
138 wq->status = -EINTR; /* Status return if interrupted */
139 memcpy(wq->name, name->name, name->len);
140 wq->next = sbi->queues;
141 sbi->queues = wq;
142
143 /* autofs_notify_daemon() may block */
144 wq->wait_ctr = 2;
145 autofs_notify_daemon(sbi,wq);
146 } else
147 wq->wait_ctr++;
148
149 /* wq->name is NULL if and only if the lock is already released */
150
151 if ( sbi->catatonic ) {
152 /* We might have slept, so check again for catatonic mode */
153 wq->status = -ENOENT;
154 kfree(wq->name);
155 wq->name = NULL;
156 }
157
158 if ( wq->name ) {
159 /* Block all but "shutdown" signals while waiting */
160 sigset_t sigmask;
161
162 siginitsetinv(&sigmask, SHUTDOWN_SIGS);
163 sigprocmask(SIG_BLOCK, &sigmask, &sigmask);
164
165 interruptible_sleep_on(&wq->queue);
166
167 sigprocmask(SIG_SETMASK, &sigmask, NULL);
168 } else {
169 DPRINTK(("autofs_wait: skipped sleeping\n"));
170 }
171
172 status = wq->status;
173
174 if ( ! --wq->wait_ctr ) /* Are we the last process to need status? */
175 kfree(wq);
176
177 return status;
178}
179
180
181int autofs_wait_release(struct autofs_sb_info *sbi, autofs_wqt_t wait_queue_token, int status)
182{
183 struct autofs_wait_queue *wq, **wql;
184
185 for (wql = &sbi->queues; (wq = *wql) != NULL; wql = &wq->next) {
186 if ( wq->wait_queue_token == wait_queue_token )
187 break;
188 }
189 if ( !wq )
190 return -EINVAL;
191
192 *wql = wq->next; /* Unlink from chain */
193 kfree(wq->name);
194 wq->name = NULL; /* Do not wait on this queue */
195
196 wq->status = status;
197
198 if ( ! --wq->wait_ctr ) /* Is anyone still waiting for this guy? */
199 kfree(wq);
200 else
201 wake_up(&wq->queue);
202
203 return 0;
204}
205