Blame view

fs/autofs4/root.c 23.4 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
  /* -*- c -*- --------------------------------------------------------------- *
   *
   * linux/fs/autofs/root.c
   *
   *  Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
   *  Copyright 1999-2000 Jeremy Fitzhardinge <jeremy@goop.org>
34ca959cf   Ian Kent   [PATCH] autofs4: ...
7
   *  Copyright 2001-2006 Ian Kent <raven@themaw.net>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
8
9
10
11
12
13
   *
   * This file is part of the Linux kernel and is made available under
   * the terms of the GNU General Public License, version 2, or at your
   * option, any later version, incorporated herein by reference.
   *
   * ------------------------------------------------------------------------- */
16f7e0fe2   Randy Dunlap   [PATCH] capable/c...
14
  #include <linux/capability.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
15
16
  #include <linux/errno.h>
  #include <linux/stat.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
17
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
19
  #include <linux/param.h>
  #include <linux/time.h>
c9243f5bd   Arnd Bergmann   autofs/autofs4: M...
20
  #include <linux/compat.h>
00e300e1b   Arnd Bergmann   BKL: Remove BKL f...
21
  #include <linux/mutex.h>
c9243f5bd   Arnd Bergmann   autofs/autofs4: M...
22

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23
24
25
26
27
  #include "autofs_i.h"
  
  static int autofs4_dir_symlink(struct inode *,struct dentry *,const char *);
  static int autofs4_dir_unlink(struct inode *,struct dentry *);
  static int autofs4_dir_rmdir(struct inode *,struct dentry *);
18bb1db3e   Al Viro   switch vfs_mkdir(...
28
  static int autofs4_dir_mkdir(struct inode *,struct dentry *,umode_t);
3663df70c   Frederic Weisbecker   autofs4: Pushdown...
29
  static long autofs4_root_ioctl(struct file *,unsigned int,unsigned long);
5a44a73b9   Felipe Contreras   autofs4: Only dec...
30
  #ifdef CONFIG_COMPAT
c9243f5bd   Arnd Bergmann   autofs/autofs4: M...
31
  static long autofs4_root_compat_ioctl(struct file *,unsigned int,unsigned long);
5a44a73b9   Felipe Contreras   autofs4: Only dec...
32
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
33
  static int autofs4_dir_open(struct inode *inode, struct file *file);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
  static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *);
71e469db2   Ian Kent   autofs4: Clean up...
35
  static struct vfsmount *autofs4_d_automount(struct path *);
1aed3e420   Al Viro   lose 'mounting_he...
36
  static int autofs4_d_manage(struct dentry *, bool);
b89b12b46   Al Viro   autofs4: clean ->...
37
  static void autofs4_dentry_release(struct dentry *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
38

4b6f5d20b   Arjan van de Ven   [PATCH] Make most...
39
  const struct file_operations autofs4_root_operations = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
40
41
42
  	.open		= dcache_dir_open,
  	.release	= dcache_dir_close,
  	.read		= generic_read_dir,
aa55ddf34   Ian Kent   autofs4: remove u...
43
  	.readdir	= dcache_readdir,
59af1584b   Al Viro   [PATCH] fix ->lls...
44
  	.llseek		= dcache_dir_lseek,
3663df70c   Frederic Weisbecker   autofs4: Pushdown...
45
  	.unlocked_ioctl	= autofs4_root_ioctl,
c9243f5bd   Arnd Bergmann   autofs/autofs4: M...
46
47
48
  #ifdef CONFIG_COMPAT
  	.compat_ioctl	= autofs4_root_compat_ioctl,
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49
  };
4b6f5d20b   Arjan van de Ven   [PATCH] Make most...
50
  const struct file_operations autofs4_dir_operations = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
51
  	.open		= autofs4_dir_open,
ff9cd499d   Ian Kent   autofs4: cleanup ...
52
  	.release	= dcache_dir_close,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
53
  	.read		= generic_read_dir,
ff9cd499d   Ian Kent   autofs4: cleanup ...
54
  	.readdir	= dcache_readdir,
59af1584b   Al Viro   [PATCH] fix ->lls...
55
  	.llseek		= dcache_dir_lseek,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56
  };
754661f14   Arjan van de Ven   [PATCH] mark stru...
57
  const struct inode_operations autofs4_dir_inode_operations = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
58
59
60
61
62
63
  	.lookup		= autofs4_lookup,
  	.unlink		= autofs4_dir_unlink,
  	.symlink	= autofs4_dir_symlink,
  	.mkdir		= autofs4_dir_mkdir,
  	.rmdir		= autofs4_dir_rmdir,
  };
71e469db2   Ian Kent   autofs4: Clean up...
64
  const struct dentry_operations autofs4_dentry_operations = {
71e469db2   Ian Kent   autofs4: Clean up...
65
66
67
68
  	.d_automount	= autofs4_d_automount,
  	.d_manage	= autofs4_d_manage,
  	.d_release	= autofs4_dentry_release,
  };
4f8427d19   Ian Kent   autofs4: use help...
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
  static void autofs4_add_active(struct dentry *dentry)
  {
  	struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
  	struct autofs_info *ino = autofs4_dentry_ino(dentry);
  	if (ino) {
  		spin_lock(&sbi->lookup_lock);
  		if (!ino->active_count) {
  			if (list_empty(&ino->active))
  				list_add(&ino->active, &sbi->active_list);
  		}
  		ino->active_count++;
  		spin_unlock(&sbi->lookup_lock);
  	}
  	return;
  }
  
  static void autofs4_del_active(struct dentry *dentry)
  {
  	struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
  	struct autofs_info *ino = autofs4_dentry_ino(dentry);
  	if (ino) {
  		spin_lock(&sbi->lookup_lock);
  		ino->active_count--;
  		if (!ino->active_count) {
  			if (!list_empty(&ino->active))
  				list_del_init(&ino->active);
  		}
  		spin_unlock(&sbi->lookup_lock);
  	}
  	return;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
100
101
  static int autofs4_dir_open(struct inode *inode, struct file *file)
  {
a4669ed8e   Josef "Jeff" Sipek   [PATCH] autofs4: ...
102
  	struct dentry *dentry = file->f_path.dentry;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
103
  	struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
f360ce3be   Ian Kent   [PATCH] autofs4: ...
104

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
105
106
107
108
109
  	DPRINTK("file=%p dentry=%p %.*s",
  		file, dentry, dentry->d_name.len, dentry->d_name.name);
  
  	if (autofs4_oz_mode(sbi))
  		goto out;
ff9cd499d   Ian Kent   autofs4: cleanup ...
110
111
112
113
114
115
116
117
118
  	/*
  	 * An empty directory in an autofs file system is always a
  	 * mount point. The daemon must have failed to mount this
  	 * during lookup so it doesn't exist. This can happen, for
  	 * example, if user space returns an incorrect status for a
  	 * mount request. Otherwise we're doing a readdir on the
  	 * autofs file system so just let the libfs routines handle
  	 * it.
  	 */
e7854723d   Ian Kent   autofs4 - remove ...
119
  	spin_lock(&sbi->lookup_lock);
2fd6b7f50   Nick Piggin   fs: dcache scale ...
120
  	spin_lock(&dentry->d_lock);
c42c7f7e6   Ian Kent   autofs4: eliminat...
121
  	if (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) {
2fd6b7f50   Nick Piggin   fs: dcache scale ...
122
  		spin_unlock(&dentry->d_lock);
e7854723d   Ian Kent   autofs4 - remove ...
123
  		spin_unlock(&sbi->lookup_lock);
ff9cd499d   Ian Kent   autofs4: cleanup ...
124
  		return -ENOENT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
125
  	}
2fd6b7f50   Nick Piggin   fs: dcache scale ...
126
  	spin_unlock(&dentry->d_lock);
e7854723d   Ian Kent   autofs4 - remove ...
127
  	spin_unlock(&sbi->lookup_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
128

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
129
  out:
ff9cd499d   Ian Kent   autofs4: cleanup ...
130
  	return dcache_dir_open(inode, file);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
131
  }
b89b12b46   Al Viro   autofs4: clean ->...
132
  static void autofs4_dentry_release(struct dentry *de)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
133
  {
b89b12b46   Al Viro   autofs4: clean ->...
134
135
  	struct autofs_info *ino = autofs4_dentry_ino(de);
  	struct autofs_sb_info *sbi = autofs4_sbi(de->d_sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
136
137
  
  	DPRINTK("releasing %p", de);
b89b12b46   Al Viro   autofs4: clean ->...
138
139
140
141
142
143
144
145
146
147
  	if (!ino)
  		return;
  
  	if (sbi) {
  		spin_lock(&sbi->lookup_lock);
  		if (!list_empty(&ino->active))
  			list_del(&ino->active);
  		if (!list_empty(&ino->expiring))
  			list_del(&ino->expiring);
  		spin_unlock(&sbi->lookup_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
148
  	}
b89b12b46   Al Viro   autofs4: clean ->...
149
150
  
  	autofs4_free_ino(ino);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
151
  }
6510c9d85   Ian Kent   autofs4: cleanup ...
152
  static struct dentry *autofs4_lookup_active(struct dentry *dentry)
257673787   Ian Kent   autofs4: use look...
153
  {
6510c9d85   Ian Kent   autofs4: cleanup ...
154
155
156
  	struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
  	struct dentry *parent = dentry->d_parent;
  	struct qstr *name = &dentry->d_name;
257673787   Ian Kent   autofs4: use look...
157
158
159
160
  	unsigned int len = name->len;
  	unsigned int hash = name->hash;
  	const unsigned char *str = name->name;
  	struct list_head *p, *head;
257673787   Ian Kent   autofs4: use look...
161
162
163
164
  	spin_lock(&sbi->lookup_lock);
  	head = &sbi->active_list;
  	list_for_each(p, head) {
  		struct autofs_info *ino;
e4d5ade7b   Ian Kent   autofs4: rename d...
165
  		struct dentry *active;
257673787   Ian Kent   autofs4: use look...
166
167
168
  		struct qstr *qstr;
  
  		ino = list_entry(p, struct autofs_info, active);
e4d5ade7b   Ian Kent   autofs4: rename d...
169
  		active = ino->dentry;
257673787   Ian Kent   autofs4: use look...
170

e4d5ade7b   Ian Kent   autofs4: rename d...
171
  		spin_lock(&active->d_lock);
257673787   Ian Kent   autofs4: use look...
172
173
  
  		/* Already gone? */
b7ab39f63   Nick Piggin   fs: dcache scale ...
174
  		if (active->d_count == 0)
257673787   Ian Kent   autofs4: use look...
175
  			goto next;
e4d5ade7b   Ian Kent   autofs4: rename d...
176
  		qstr = &active->d_name;
257673787   Ian Kent   autofs4: use look...
177

e4d5ade7b   Ian Kent   autofs4: rename d...
178
  		if (active->d_name.hash != hash)
257673787   Ian Kent   autofs4: use look...
179
  			goto next;
e4d5ade7b   Ian Kent   autofs4: rename d...
180
  		if (active->d_parent != parent)
257673787   Ian Kent   autofs4: use look...
181
182
183
184
185
186
  			goto next;
  
  		if (qstr->len != len)
  			goto next;
  		if (memcmp(qstr->name, str, len))
  			goto next;
4b1ae27a9   Al Viro   Revert "autofs4: ...
187
  		if (d_unhashed(active)) {
b7ab39f63   Nick Piggin   fs: dcache scale ...
188
  			dget_dlock(active);
4b1ae27a9   Al Viro   Revert "autofs4: ...
189
190
  			spin_unlock(&active->d_lock);
  			spin_unlock(&sbi->lookup_lock);
4b1ae27a9   Al Viro   Revert "autofs4: ...
191
192
  			return active;
  		}
257673787   Ian Kent   autofs4: use look...
193
  next:
e4d5ade7b   Ian Kent   autofs4: rename d...
194
  		spin_unlock(&active->d_lock);
257673787   Ian Kent   autofs4: use look...
195
196
  	}
  	spin_unlock(&sbi->lookup_lock);
257673787   Ian Kent   autofs4: use look...
197
198
199
  
  	return NULL;
  }
6510c9d85   Ian Kent   autofs4: cleanup ...
200
  static struct dentry *autofs4_lookup_expiring(struct dentry *dentry)
f50b6f869   Ian Kent   [PATCH] autofs4: ...
201
  {
6510c9d85   Ian Kent   autofs4: cleanup ...
202
203
204
  	struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
  	struct dentry *parent = dentry->d_parent;
  	struct qstr *name = &dentry->d_name;
f50b6f869   Ian Kent   [PATCH] autofs4: ...
205
206
207
208
  	unsigned int len = name->len;
  	unsigned int hash = name->hash;
  	const unsigned char *str = name->name;
  	struct list_head *p, *head;
5f6f4f28b   Ian Kent   autofs4: don't ma...
209
210
  	spin_lock(&sbi->lookup_lock);
  	head = &sbi->expiring_list;
f50b6f869   Ian Kent   [PATCH] autofs4: ...
211
212
  	list_for_each(p, head) {
  		struct autofs_info *ino;
cb4b492ac   Ian Kent   autofs4: rename d...
213
  		struct dentry *expiring;
f50b6f869   Ian Kent   [PATCH] autofs4: ...
214
  		struct qstr *qstr;
5f6f4f28b   Ian Kent   autofs4: don't ma...
215
  		ino = list_entry(p, struct autofs_info, expiring);
cb4b492ac   Ian Kent   autofs4: rename d...
216
  		expiring = ino->dentry;
f50b6f869   Ian Kent   [PATCH] autofs4: ...
217

cb4b492ac   Ian Kent   autofs4: rename d...
218
  		spin_lock(&expiring->d_lock);
f50b6f869   Ian Kent   [PATCH] autofs4: ...
219
220
  
  		/* Bad luck, we've already been dentry_iput */
cb4b492ac   Ian Kent   autofs4: rename d...
221
  		if (!expiring->d_inode)
f50b6f869   Ian Kent   [PATCH] autofs4: ...
222
  			goto next;
cb4b492ac   Ian Kent   autofs4: rename d...
223
  		qstr = &expiring->d_name;
f50b6f869   Ian Kent   [PATCH] autofs4: ...
224

cb4b492ac   Ian Kent   autofs4: rename d...
225
  		if (expiring->d_name.hash != hash)
f50b6f869   Ian Kent   [PATCH] autofs4: ...
226
  			goto next;
cb4b492ac   Ian Kent   autofs4: rename d...
227
  		if (expiring->d_parent != parent)
f50b6f869   Ian Kent   [PATCH] autofs4: ...
228
229
230
231
232
233
  			goto next;
  
  		if (qstr->len != len)
  			goto next;
  		if (memcmp(qstr->name, str, len))
  			goto next;
4b1ae27a9   Al Viro   Revert "autofs4: ...
234
  		if (d_unhashed(expiring)) {
b7ab39f63   Nick Piggin   fs: dcache scale ...
235
  			dget_dlock(expiring);
4b1ae27a9   Al Viro   Revert "autofs4: ...
236
237
  			spin_unlock(&expiring->d_lock);
  			spin_unlock(&sbi->lookup_lock);
4b1ae27a9   Al Viro   Revert "autofs4: ...
238
239
  			return expiring;
  		}
f50b6f869   Ian Kent   [PATCH] autofs4: ...
240
  next:
cb4b492ac   Ian Kent   autofs4: rename d...
241
  		spin_unlock(&expiring->d_lock);
f50b6f869   Ian Kent   [PATCH] autofs4: ...
242
  	}
5f6f4f28b   Ian Kent   autofs4: don't ma...
243
  	spin_unlock(&sbi->lookup_lock);
f50b6f869   Ian Kent   [PATCH] autofs4: ...
244
245
246
  
  	return NULL;
  }
10584211e   Ian Kent   autofs4: Add d_au...
247
248
249
250
  static int autofs4_mount_wait(struct dentry *dentry)
  {
  	struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
  	struct autofs_info *ino = autofs4_dentry_ino(dentry);
3c3199852   Ian Kent   autofs4 - reinsta...
251
  	int status = 0;
10584211e   Ian Kent   autofs4: Add d_au...
252
253
254
255
256
257
  
  	if (ino->flags & AUTOFS_INF_PENDING) {
  		DPRINTK("waiting for mount name=%.*s",
  			dentry->d_name.len, dentry->d_name.name);
  		status = autofs4_wait(sbi, dentry, NFY_MOUNT);
  		DPRINTK("mount wait done status=%d", status);
10584211e   Ian Kent   autofs4: Add d_au...
258
  	}
3c3199852   Ian Kent   autofs4 - reinsta...
259
260
  	ino->last_used = jiffies;
  	return status;
10584211e   Ian Kent   autofs4: Add d_au...
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
  }
  
  static int do_expire_wait(struct dentry *dentry)
  {
  	struct dentry *expiring;
  
  	expiring = autofs4_lookup_expiring(dentry);
  	if (!expiring)
  		return autofs4_expire_wait(dentry);
  	else {
  		/*
  		 * If we are racing with expire the request might not
  		 * be quite complete, but the directory has been removed
  		 * so it must have been successful, just wait for it.
  		 */
  		autofs4_expire_wait(expiring);
  		autofs4_del_expiring(expiring);
  		dput(expiring);
  	}
  	return 0;
  }
  
  static struct dentry *autofs4_mountpoint_changed(struct path *path)
  {
  	struct dentry *dentry = path->dentry;
  	struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
  
  	/*
  	 * If this is an indirect mount the dentry could have gone away
  	 * as a result of an expire and a new one created.
  	 */
  	if (autofs_type_indirect(sbi->type) && d_unhashed(dentry)) {
  		struct dentry *parent = dentry->d_parent;
3c3199852   Ian Kent   autofs4 - reinsta...
294
  		struct autofs_info *ino;
10584211e   Ian Kent   autofs4: Add d_au...
295
296
297
  		struct dentry *new = d_lookup(parent, &dentry->d_name);
  		if (!new)
  			return NULL;
3c3199852   Ian Kent   autofs4 - reinsta...
298
299
  		ino = autofs4_dentry_ino(new);
  		ino->last_used = jiffies;
10584211e   Ian Kent   autofs4: Add d_au...
300
301
302
303
304
  		dput(path->dentry);
  		path->dentry = new;
  	}
  	return path->dentry;
  }
71e469db2   Ian Kent   autofs4: Clean up...
305
  static struct vfsmount *autofs4_d_automount(struct path *path)
10584211e   Ian Kent   autofs4: Add d_au...
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
  {
  	struct dentry *dentry = path->dentry;
  	struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
  	struct autofs_info *ino = autofs4_dentry_ino(dentry);
  	int status;
  
  	DPRINTK("dentry=%p %.*s",
  		dentry, dentry->d_name.len, dentry->d_name.name);
  
  	/* The daemon never triggers a mount. */
  	if (autofs4_oz_mode(sbi))
  		return NULL;
  
  	/*
  	 * If an expire request is pending everyone must wait.
  	 * If the expire fails we're still mounted so continue
  	 * the follow and return. A return of -EAGAIN (which only
  	 * happens with indirect mounts) means the expire completed
  	 * and the directory was removed, so just go ahead and try
  	 * the mount.
  	 */
  	status = do_expire_wait(dentry);
  	if (status && status != -EAGAIN)
  		return NULL;
  
  	/* Callback to the daemon to perform the mount or wait */
  	spin_lock(&sbi->fs_lock);
  	if (ino->flags & AUTOFS_INF_PENDING) {
  		spin_unlock(&sbi->fs_lock);
  		status = autofs4_mount_wait(dentry);
  		if (status)
  			return ERR_PTR(status);
  		spin_lock(&sbi->fs_lock);
  		goto done;
  	}
  
  	/*
  	 * If the dentry is a symlink it's equivalent to a directory
b5b801779   Ian Kent   autofs4: Add d_ma...
344
  	 * having d_mountpoint() true, so there's no need to call back
10584211e   Ian Kent   autofs4: Add d_au...
345
346
347
348
  	 * to the daemon.
  	 */
  	if (dentry->d_inode && S_ISLNK(dentry->d_inode->i_mode))
  		goto done;
b5b801779   Ian Kent   autofs4: Add d_ma...
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
  	if (!d_mountpoint(dentry)) {
  		/*
  		 * It's possible that user space hasn't removed directories
  		 * after umounting a rootless multi-mount, although it
  		 * should. For v5 have_submounts() is sufficient to handle
  		 * this because the leaves of the directory tree under the
  		 * mount never trigger mounts themselves (they have an autofs
  		 * trigger mount mounted on them). But v4 pseudo direct mounts
  		 * do need the leaves to to trigger mounts. In this case we
  		 * have no choice but to use the list_empty() check and
  		 * require user space behave.
  		 */
  		if (sbi->version > 4) {
  			if (have_submounts(dentry))
  				goto done;
  		} else {
  			spin_lock(&dentry->d_lock);
  			if (!list_empty(&dentry->d_subdirs)) {
  				spin_unlock(&dentry->d_lock);
  				goto done;
  			}
  			spin_unlock(&dentry->d_lock);
  		}
10584211e   Ian Kent   autofs4: Add d_au...
372
  		ino->flags |= AUTOFS_INF_PENDING;
10584211e   Ian Kent   autofs4: Add d_au...
373
374
375
376
377
378
  		spin_unlock(&sbi->fs_lock);
  		status = autofs4_mount_wait(dentry);
  		if (status)
  			return ERR_PTR(status);
  		spin_lock(&sbi->fs_lock);
  		ino->flags &= ~AUTOFS_INF_PENDING;
10584211e   Ian Kent   autofs4: Add d_au...
379
  	}
10584211e   Ian Kent   autofs4: Add d_au...
380
  done:
b5b801779   Ian Kent   autofs4: Add d_ma...
381
382
  	if (!(ino->flags & AUTOFS_INF_EXPIRING)) {
  		/*
3c3199852   Ian Kent   autofs4 - reinsta...
383
384
385
386
387
  		 * Any needed mounting has been completed and the path
  		 * updated so clear DCACHE_NEED_AUTOMOUNT so we don't
  		 * call ->d_automount() on rootless multi-mounts since
  		 * it can lead to an incorrect ELOOP error return.
  		 *
b5b801779   Ian Kent   autofs4: Add d_ma...
388
389
390
391
392
  		 * Only clear DMANAGED_AUTOMOUNT for rootless multi-mounts and
  		 * symlinks as in all other cases the dentry will be covered by
  		 * an actual mount so ->d_automount() won't be called during
  		 * the follow.
  		 */
3c3199852   Ian Kent   autofs4 - reinsta...
393
  		spin_lock(&dentry->d_lock);
b5b801779   Ian Kent   autofs4: Add d_ma...
394
395
396
397
398
399
  		if ((!d_mountpoint(dentry) &&
  		    !list_empty(&dentry->d_subdirs)) ||
  		    (dentry->d_inode && S_ISLNK(dentry->d_inode->i_mode)))
  			__managed_dentry_clear_automount(dentry);
  		spin_unlock(&dentry->d_lock);
  	}
10584211e   Ian Kent   autofs4: Add d_au...
400
401
402
403
404
405
406
407
408
  	spin_unlock(&sbi->fs_lock);
  
  	/* Mount succeeded, check if we ended up with a new dentry */
  	dentry = autofs4_mountpoint_changed(path);
  	if (!dentry)
  		return ERR_PTR(-ENOENT);
  
  	return NULL;
  }
1aed3e420   Al Viro   lose 'mounting_he...
409
  int autofs4_d_manage(struct dentry *dentry, bool rcu_walk)
b5b801779   Ian Kent   autofs4: Add d_ma...
410
411
412
413
414
415
416
  {
  	struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
  
  	DPRINTK("dentry=%p %.*s",
  		dentry, dentry->d_name.len, dentry->d_name.name);
  
  	/* The daemon never waits. */
1aed3e420   Al Viro   lose 'mounting_he...
417
  	if (autofs4_oz_mode(sbi)) {
83fb96bfc   Ian Kent   autofs4 - fix d_m...
418
419
  		if (rcu_walk)
  			return 0;
b5b801779   Ian Kent   autofs4: Add d_ma...
420
421
422
423
  		if (!d_mountpoint(dentry))
  			return -EISDIR;
  		return 0;
  	}
ab90911ff   David Howells   Allow d_manage() ...
424
425
426
  	/* We need to sleep, so we need pathwalk to be in ref-mode */
  	if (rcu_walk)
  		return -ECHILD;
b5b801779   Ian Kent   autofs4: Add d_ma...
427
428
429
430
431
432
433
434
435
  	/* Wait for pending expires */
  	do_expire_wait(dentry);
  
  	/*
  	 * This dentry may be under construction so wait on mount
  	 * completion.
  	 */
  	return autofs4_mount_wait(dentry);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
436
437
438
439
  /* Lookups in the root directory */
  static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
  {
  	struct autofs_sb_info *sbi;
257673787   Ian Kent   autofs4: use look...
440
  	struct autofs_info *ino;
10584211e   Ian Kent   autofs4: Add d_au...
441
  	struct dentry *active;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
442

10584211e   Ian Kent   autofs4: Add d_au...
443
  	DPRINTK("name = %.*s", dentry->d_name.len, dentry->d_name.name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
444

718c604a2   Ian Kent   [PATCH] autofs4: ...
445
  	/* File name too long to exist */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
446
  	if (dentry->d_name.len > NAME_MAX)
718c604a2   Ian Kent   [PATCH] autofs4: ...
447
  		return ERR_PTR(-ENAMETOOLONG);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
448
449
  
  	sbi = autofs4_sbi(dir->i_sb);
718c604a2   Ian Kent   [PATCH] autofs4: ...
450

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
451
  	DPRINTK("pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d",
c0bcc9d55   Ian Kent   autofs4 - fix deb...
452
453
  		current->pid, task_pgrp_nr(current), sbi->catatonic,
  		autofs4_oz_mode(sbi));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
454

6510c9d85   Ian Kent   autofs4: cleanup ...
455
  	active = autofs4_lookup_active(dentry);
90387c9c1   Ian Kent   autofs4: renamer ...
456
  	if (active) {
10584211e   Ian Kent   autofs4: Add d_au...
457
  		return active;
aa952eb26   Ian Kent   autofs4: use auto...
458
  	} else {
4b1ae27a9   Al Viro   Revert "autofs4: ...
459
  		/*
10584211e   Ian Kent   autofs4: Add d_au...
460
461
462
463
  		 * A dentry that is not within the root can never trigger a
  		 * mount operation, unless the directory already exists, so we
  		 * can return fail immediately.  The daemon however does need
  		 * to create directories within the file system.
4b1ae27a9   Al Viro   Revert "autofs4: ...
464
  		 */
10584211e   Ian Kent   autofs4: Add d_au...
465
466
467
468
  		if (!autofs4_oz_mode(sbi) && !IS_ROOT(dentry->d_parent))
  			return ERR_PTR(-ENOENT);
  
  		/* Mark entries in the root as mount triggers */
b650c858c   David Howells   autofs4: Merge th...
469
  		if (autofs_type_indirect(sbi->type) && IS_ROOT(dentry->d_parent))
b5b801779   Ian Kent   autofs4: Add d_ma...
470
  			__managed_dentry_set_managed(dentry);
10584211e   Ian Kent   autofs4: Add d_au...
471

26e6c9106   Al Viro   autofs4: split au...
472
  		ino = autofs4_new_ino(sbi);
4b1ae27a9   Al Viro   Revert "autofs4: ...
473
474
475
476
477
  		if (!ino)
  			return ERR_PTR(-ENOMEM);
  
  		dentry->d_fsdata = ino;
  		ino->dentry = dentry;
5f6f4f28b   Ian Kent   autofs4: don't ma...
478

4b1ae27a9   Al Viro   Revert "autofs4: ...
479
480
481
482
  		autofs4_add_active(dentry);
  
  		d_instantiate(dentry, NULL);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
483
484
485
486
487
488
489
490
491
  	return NULL;
  }
  
  static int autofs4_dir_symlink(struct inode *dir, 
  			       struct dentry *dentry,
  			       const char *symname)
  {
  	struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
  	struct autofs_info *ino = autofs4_dentry_ino(dentry);
1aff3c8b0   Ian Kent   [PATCH] autofs4: ...
492
  	struct autofs_info *p_ino;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
493
  	struct inode *inode;
0bf71d4d0   Al Viro   autofs4: kill ->s...
494
  	size_t size = strlen(symname);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
495
496
497
498
499
500
501
  	char *cp;
  
  	DPRINTK("%s <- %.*s", symname,
  		dentry->d_name.len, dentry->d_name.name);
  
  	if (!autofs4_oz_mode(sbi))
  		return -EACCES;
5a37db302   Al Viro   autofs4: mkdir an...
502
  	BUG_ON(!ino);
26e6c9106   Al Viro   autofs4: split au...
503
  	autofs4_clean_ino(ino);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
504

4b1ae27a9   Al Viro   Revert "autofs4: ...
505
  	autofs4_del_active(dentry);
0bf71d4d0   Al Viro   autofs4: kill ->s...
506
  	cp = kmalloc(size + 1, GFP_KERNEL);
5a37db302   Al Viro   autofs4: mkdir an...
507
  	if (!cp)
257673787   Ian Kent   autofs4: use look...
508
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
509
510
  
  	strcpy(cp, symname);
726a5e068   Al Viro   autofs4: autofs4_...
511
  	inode = autofs4_get_inode(dir->i_sb, S_IFLNK | 0555);
257673787   Ian Kent   autofs4: use look...
512
513
514
515
516
517
  	if (!inode) {
  		kfree(cp);
  		if (!dentry->d_fsdata)
  			kfree(ino);
  		return -ENOMEM;
  	}
292c5ee80   Al Viro   autofs4: keep sym...
518
  	inode->i_private = cp;
0bf71d4d0   Al Viro   autofs4: kill ->s...
519
  	inode->i_size = size;
1864f7bd5   Ian Kent   autofs4: deadlock...
520
  	d_add(dentry, inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
521

5a37db302   Al Viro   autofs4: mkdir an...
522
  	dget(dentry);
1aff3c8b0   Ian Kent   [PATCH] autofs4: ...
523
524
525
526
  	atomic_inc(&ino->count);
  	p_ino = autofs4_dentry_ino(dentry->d_parent);
  	if (p_ino && dentry->d_parent != dentry)
  		atomic_inc(&p_ino->count);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
527
528
529
530
531
532
533
534
535
536
537
538
  
  	dir->i_mtime = CURRENT_TIME;
  
  	return 0;
  }
  
  /*
   * NOTE!
   *
   * Normal filesystems would do a "d_delete()" to tell the VFS dcache
   * that the file no longer exists. However, doing that means that the
   * VFS layer can turn the dentry into a negative dentry.  We don't want
f50b6f869   Ian Kent   [PATCH] autofs4: ...
539
   * this, because the unlink is probably the result of an expire.
5f6f4f28b   Ian Kent   autofs4: don't ma...
540
541
   * We simply d_drop it and add it to a expiring list in the super block,
   * which allows the dentry lookup to check for an incomplete expire.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
542
543
544
545
546
547
548
549
550
551
   *
   * If a process is blocked on the dentry waiting for the expire to finish,
   * it will invalidate the dentry and try to mount with a new one.
   *
   * Also see autofs4_dir_rmdir()..
   */
  static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry)
  {
  	struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
  	struct autofs_info *ino = autofs4_dentry_ino(dentry);
1aff3c8b0   Ian Kent   [PATCH] autofs4: ...
552
  	struct autofs_info *p_ino;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
553
554
  	
  	/* This allows root to remove symlinks */
d78e53c89   Sukadev Bhattiprolu   Fix some coding-s...
555
  	if (!autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
556
  		return -EACCES;
1aff3c8b0   Ian Kent   [PATCH] autofs4: ...
557
558
559
560
561
  	if (atomic_dec_and_test(&ino->count)) {
  		p_ino = autofs4_dentry_ino(dentry->d_parent);
  		if (p_ino && dentry->d_parent != dentry)
  			atomic_dec(&p_ino->count);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
562
563
564
  	dput(ino->dentry);
  
  	dentry->d_inode->i_size = 0;
ce71ec368   Dave Hansen   [PATCH] r/o bind ...
565
  	clear_nlink(dentry->d_inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
566
567
  
  	dir->i_mtime = CURRENT_TIME;
e7854723d   Ian Kent   autofs4 - remove ...
568
569
  	spin_lock(&sbi->lookup_lock);
  	__autofs4_add_expiring(dentry);
f50b6f869   Ian Kent   [PATCH] autofs4: ...
570
571
572
  	spin_lock(&dentry->d_lock);
  	__d_drop(dentry);
  	spin_unlock(&dentry->d_lock);
e7854723d   Ian Kent   autofs4 - remove ...
573
  	spin_unlock(&sbi->lookup_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
574
575
576
  
  	return 0;
  }
dd89f90d2   Ian Kent   autofs4: Add v4 p...
577
578
579
580
581
582
583
  /*
   * Version 4 of autofs provides a pseudo direct mount implementation
   * that relies on directories at the leaves of a directory tree under
   * an indirect mount to trigger mounts. To allow for this we need to
   * set the DMANAGED_AUTOMOUNT and DMANAGED_TRANSIT flags on the leaves
   * of the directory tree. There is no need to clear the automount flag
   * following a mount or restore it after an expire because these mounts
25985edce   Lucas De Marchi   Fix common misspe...
584
   * are always covered. However, it is necessary to ensure that these
dd89f90d2   Ian Kent   autofs4: Add v4 p...
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
   * flags are clear on non-empty directories to avoid unnecessary calls
   * during path walks.
   */
  static void autofs_set_leaf_automount_flags(struct dentry *dentry)
  {
  	struct dentry *parent;
  
  	/* root and dentrys in the root are already handled */
  	if (IS_ROOT(dentry->d_parent))
  		return;
  
  	managed_dentry_set_managed(dentry);
  
  	parent = dentry->d_parent;
  	/* only consider parents below dentrys in the root */
  	if (IS_ROOT(parent->d_parent))
  		return;
  	managed_dentry_clear_managed(parent);
  	return;
  }
  
  static void autofs_clear_leaf_automount_flags(struct dentry *dentry)
  {
  	struct list_head *d_child;
  	struct dentry *parent;
  
  	/* flags for dentrys in the root are handled elsewhere */
  	if (IS_ROOT(dentry->d_parent))
  		return;
  
  	managed_dentry_clear_managed(dentry);
  
  	parent = dentry->d_parent;
  	/* only consider parents below dentrys in the root */
  	if (IS_ROOT(parent->d_parent))
  		return;
  	d_child = &dentry->d_u.d_child;
  	/* Set parent managed if it's becoming empty */
  	if (d_child->next == &parent->d_subdirs &&
  	    d_child->prev == &parent->d_subdirs)
  		managed_dentry_set_managed(parent);
  	return;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
628
629
630
631
  static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry)
  {
  	struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
  	struct autofs_info *ino = autofs4_dentry_ino(dentry);
1aff3c8b0   Ian Kent   [PATCH] autofs4: ...
632
  	struct autofs_info *p_ino;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
633
  	
f50b6f869   Ian Kent   [PATCH] autofs4: ...
634
635
  	DPRINTK("dentry %p, removing %.*s",
  		dentry, dentry->d_name.len, dentry->d_name.name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
636
637
  	if (!autofs4_oz_mode(sbi))
  		return -EACCES;
2fd6b7f50   Nick Piggin   fs: dcache scale ...
638
639
  	spin_lock(&sbi->lookup_lock);
  	spin_lock(&dentry->d_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
640
  	if (!list_empty(&dentry->d_subdirs)) {
2fd6b7f50   Nick Piggin   fs: dcache scale ...
641
642
  		spin_unlock(&dentry->d_lock);
  		spin_unlock(&sbi->lookup_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
643
644
  		return -ENOTEMPTY;
  	}
2fd6b7f50   Nick Piggin   fs: dcache scale ...
645
  	__autofs4_add_expiring(dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
646
647
  	__d_drop(dentry);
  	spin_unlock(&dentry->d_lock);
e7854723d   Ian Kent   autofs4 - remove ...
648
  	spin_unlock(&sbi->lookup_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
649

dd89f90d2   Ian Kent   autofs4: Add v4 p...
650
651
  	if (sbi->version < 5)
  		autofs_clear_leaf_automount_flags(dentry);
1aff3c8b0   Ian Kent   [PATCH] autofs4: ...
652
653
654
655
656
  	if (atomic_dec_and_test(&ino->count)) {
  		p_ino = autofs4_dentry_ino(dentry->d_parent);
  		if (p_ino && dentry->d_parent != dentry)
  			atomic_dec(&p_ino->count);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
657
  	dput(ino->dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
658
  	dentry->d_inode->i_size = 0;
ce71ec368   Dave Hansen   [PATCH] r/o bind ...
659
  	clear_nlink(dentry->d_inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
660
661
  
  	if (dir->i_nlink)
9a53c3a78   Dave Hansen   [PATCH] r/o bind ...
662
  		drop_nlink(dir);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
663
664
665
  
  	return 0;
  }
18bb1db3e   Al Viro   switch vfs_mkdir(...
666
  static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
667
668
669
  {
  	struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
  	struct autofs_info *ino = autofs4_dentry_ino(dentry);
1aff3c8b0   Ian Kent   [PATCH] autofs4: ...
670
  	struct autofs_info *p_ino;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
671
  	struct inode *inode;
d78e53c89   Sukadev Bhattiprolu   Fix some coding-s...
672
  	if (!autofs4_oz_mode(sbi))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
673
674
675
676
  		return -EACCES;
  
  	DPRINTK("dentry %p, creating %.*s",
  		dentry, dentry->d_name.len, dentry->d_name.name);
5a37db302   Al Viro   autofs4: mkdir an...
677
  	BUG_ON(!ino);
26e6c9106   Al Viro   autofs4: split au...
678
  	autofs4_clean_ino(ino);
257673787   Ian Kent   autofs4: use look...
679

4b1ae27a9   Al Viro   Revert "autofs4: ...
680
  	autofs4_del_active(dentry);
726a5e068   Al Viro   autofs4: autofs4_...
681
  	inode = autofs4_get_inode(dir->i_sb, S_IFDIR | 0555);
5a37db302   Al Viro   autofs4: mkdir an...
682
  	if (!inode)
257673787   Ian Kent   autofs4: use look...
683
  		return -ENOMEM;
1864f7bd5   Ian Kent   autofs4: deadlock...
684
  	d_add(dentry, inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
685

dd89f90d2   Ian Kent   autofs4: Add v4 p...
686
687
  	if (sbi->version < 5)
  		autofs_set_leaf_automount_flags(dentry);
5a37db302   Al Viro   autofs4: mkdir an...
688
  	dget(dentry);
1aff3c8b0   Ian Kent   [PATCH] autofs4: ...
689
690
691
692
  	atomic_inc(&ino->count);
  	p_ino = autofs4_dentry_ino(dentry->d_parent);
  	if (p_ino && dentry->d_parent != dentry)
  		atomic_inc(&p_ino->count);
d8c76e6f4   Dave Hansen   [PATCH] r/o bind ...
693
  	inc_nlink(dir);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
694
695
696
697
698
699
  	dir->i_mtime = CURRENT_TIME;
  
  	return 0;
  }
  
  /* Get/set timeout ioctl() operation */
c9243f5bd   Arnd Bergmann   autofs/autofs4: M...
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
  #ifdef CONFIG_COMPAT
  static inline int autofs4_compat_get_set_timeout(struct autofs_sb_info *sbi,
  					 compat_ulong_t __user *p)
  {
  	int rv;
  	unsigned long ntimeout;
  
  	if ((rv = get_user(ntimeout, p)) ||
  	     (rv = put_user(sbi->exp_timeout/HZ, p)))
  		return rv;
  
  	if (ntimeout > UINT_MAX/HZ)
  		sbi->exp_timeout = 0;
  	else
  		sbi->exp_timeout = ntimeout * HZ;
  
  	return 0;
  }
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
719
720
721
722
723
  static inline int autofs4_get_set_timeout(struct autofs_sb_info *sbi,
  					 unsigned long __user *p)
  {
  	int rv;
  	unsigned long ntimeout;
d78e53c89   Sukadev Bhattiprolu   Fix some coding-s...
724
725
  	if ((rv = get_user(ntimeout, p)) ||
  	     (rv = put_user(sbi->exp_timeout/HZ, p)))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
726
  		return rv;
d78e53c89   Sukadev Bhattiprolu   Fix some coding-s...
727
  	if (ntimeout > ULONG_MAX/HZ)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
  		sbi->exp_timeout = 0;
  	else
  		sbi->exp_timeout = ntimeout * HZ;
  
  	return 0;
  }
  
  /* Return protocol version */
  static inline int autofs4_get_protover(struct autofs_sb_info *sbi, int __user *p)
  {
  	return put_user(sbi->version, p);
  }
  
  /* Return protocol sub version */
  static inline int autofs4_get_protosubver(struct autofs_sb_info *sbi, int __user *p)
  {
  	return put_user(sbi->sub_version, p);
  }
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
748
749
750
751
752
  * Tells the daemon whether it can umount the autofs mount.
  */
  static inline int autofs4_ask_umount(struct vfsmount *mnt, int __user *p)
  {
  	int status = 0;
e3474a8eb   Ian Kent   [PATCH] autofs4: ...
753
  	if (may_umount(mnt))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
  		status = 1;
  
  	DPRINTK("returning %d", status);
  
  	status = put_user(status, p);
  
  	return status;
  }
  
  /* Identify autofs4_dentries - this is so we can tell if there's
     an extra dentry refcount or not.  We only hold a refcount on the
     dentry if its non-negative (ie, d_inode != NULL)
  */
  int is_autofs4_dentry(struct dentry *dentry)
  {
  	return dentry && dentry->d_inode &&
b650c858c   David Howells   autofs4: Merge th...
770
  		dentry->d_op == &autofs4_dentry_operations &&
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
771
772
773
774
775
776
777
  		dentry->d_fsdata != NULL;
  }
  
  /*
   * ioctl()'s on the root directory is the chief method for the daemon to
   * generate kernel reactions
   */
3663df70c   Frederic Weisbecker   autofs4: Pushdown...
778
779
  static int autofs4_root_ioctl_unlocked(struct inode *inode, struct file *filp,
  				       unsigned int cmd, unsigned long arg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
780
781
782
783
784
  {
  	struct autofs_sb_info *sbi = autofs4_sbi(inode->i_sb);
  	void __user *p = (void __user *)arg;
  
  	DPRINTK("cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u",
a47afb0f9   Pavel Emelianov   pid namespaces: r...
785
  		cmd,arg,sbi,task_pgrp_nr(current));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
786

d78e53c89   Sukadev Bhattiprolu   Fix some coding-s...
787
788
  	if (_IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) ||
  	     _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
789
790
  		return -ENOTTY;
  	
d78e53c89   Sukadev Bhattiprolu   Fix some coding-s...
791
  	if (!autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
  		return -EPERM;
  	
  	switch(cmd) {
  	case AUTOFS_IOC_READY:	/* Wait queue: go ahead and retry */
  		return autofs4_wait_release(sbi,(autofs_wqt_t)arg,0);
  	case AUTOFS_IOC_FAIL:	/* Wait queue: fail with ENOENT */
  		return autofs4_wait_release(sbi,(autofs_wqt_t)arg,-ENOENT);
  	case AUTOFS_IOC_CATATONIC: /* Enter catatonic mode (daemon shutdown) */
  		autofs4_catatonic_mode(sbi);
  		return 0;
  	case AUTOFS_IOC_PROTOVER: /* Get protocol version */
  		return autofs4_get_protover(sbi, p);
  	case AUTOFS_IOC_PROTOSUBVER: /* Get protocol sub version */
  		return autofs4_get_protosubver(sbi, p);
  	case AUTOFS_IOC_SETTIMEOUT:
  		return autofs4_get_set_timeout(sbi, p);
c9243f5bd   Arnd Bergmann   autofs/autofs4: M...
808
809
810
811
  #ifdef CONFIG_COMPAT
  	case AUTOFS_IOC_SETTIMEOUT32:
  		return autofs4_compat_get_set_timeout(sbi, p);
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
812

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
813
  	case AUTOFS_IOC_ASKUMOUNT:
a4669ed8e   Josef "Jeff" Sipek   [PATCH] autofs4: ...
814
  		return autofs4_ask_umount(filp->f_path.mnt, p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
815
816
817
  
  	/* return a single thing to expire */
  	case AUTOFS_IOC_EXPIRE:
a4669ed8e   Josef "Jeff" Sipek   [PATCH] autofs4: ...
818
  		return autofs4_expire_run(inode->i_sb,filp->f_path.mnt,sbi, p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
819
820
  	/* same as above, but can send multiple expires through pipe */
  	case AUTOFS_IOC_EXPIRE_MULTI:
a4669ed8e   Josef "Jeff" Sipek   [PATCH] autofs4: ...
821
  		return autofs4_expire_multi(inode->i_sb,filp->f_path.mnt,sbi, p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
822
823
824
825
826
  
  	default:
  		return -ENOSYS;
  	}
  }
3663df70c   Frederic Weisbecker   autofs4: Pushdown...
827
828
829
830
  
  static long autofs4_root_ioctl(struct file *filp,
  			       unsigned int cmd, unsigned long arg)
  {
3663df70c   Frederic Weisbecker   autofs4: Pushdown...
831
  	struct inode *inode = filp->f_dentry->d_inode;
de47de740   Ian Kent   autofs4 - remove ...
832
  	return autofs4_root_ioctl_unlocked(inode, filp, cmd, arg);
3663df70c   Frederic Weisbecker   autofs4: Pushdown...
833
  }
c9243f5bd   Arnd Bergmann   autofs/autofs4: M...
834
835
836
837
838
839
840
  
  #ifdef CONFIG_COMPAT
  static long autofs4_root_compat_ioctl(struct file *filp,
  			     unsigned int cmd, unsigned long arg)
  {
  	struct inode *inode = filp->f_path.dentry->d_inode;
  	int ret;
c9243f5bd   Arnd Bergmann   autofs/autofs4: M...
841
842
843
844
845
  	if (cmd == AUTOFS_IOC_READY || cmd == AUTOFS_IOC_FAIL)
  		ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, arg);
  	else
  		ret = autofs4_root_ioctl_unlocked(inode, filp, cmd,
  			(unsigned long)compat_ptr(arg));
c9243f5bd   Arnd Bergmann   autofs/autofs4: M...
846
847
848
849
  
  	return ret;
  }
  #endif