Blame view
fs/autofs4/root.c
23.8 KB
e9a7c2f1a autofs4: coding s... |
1 2 3 4 |
/* * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved * Copyright 1999-2000 Jeremy Fitzhardinge <jeremy@goop.org> * Copyright 2001-2006 Ian Kent <raven@themaw.net> |
1da177e4c Linux-2.6.12-rc2 |
5 6 7 8 |
* * 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. |
e9a7c2f1a autofs4: coding s... |
9 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
10 |
|
16f7e0fe2 [PATCH] capable/c... |
11 |
#include <linux/capability.h> |
1da177e4c Linux-2.6.12-rc2 |
12 13 |
#include <linux/errno.h> #include <linux/stat.h> |
5a0e3ad6a include cleanup: ... |
14 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
15 16 |
#include <linux/param.h> #include <linux/time.h> |
c9243f5bd autofs/autofs4: M... |
17 |
#include <linux/compat.h> |
00e300e1b BKL: Remove BKL f... |
18 |
#include <linux/mutex.h> |
c9243f5bd autofs/autofs4: M... |
19 |
|
1da177e4c Linux-2.6.12-rc2 |
20 |
#include "autofs_i.h" |
e9a7c2f1a autofs4: coding s... |
21 22 23 24 25 |
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 *); static int autofs4_dir_mkdir(struct inode *, struct dentry *, umode_t); static long autofs4_root_ioctl(struct file *, unsigned int, unsigned long); |
5a44a73b9 autofs4: Only dec... |
26 |
#ifdef CONFIG_COMPAT |
e9a7c2f1a autofs4: coding s... |
27 28 |
static long autofs4_root_compat_ioctl(struct file *, unsigned int, unsigned long); |
5a44a73b9 autofs4: Only dec... |
29 |
#endif |
1da177e4c Linux-2.6.12-rc2 |
30 |
static int autofs4_dir_open(struct inode *inode, struct file *file); |
e9a7c2f1a autofs4: coding s... |
31 32 |
static struct dentry *autofs4_lookup(struct inode *, struct dentry *, unsigned int); |
71e469db2 autofs4: Clean up... |
33 |
static struct vfsmount *autofs4_d_automount(struct path *); |
1aed3e420 lose 'mounting_he... |
34 |
static int autofs4_d_manage(struct dentry *, bool); |
b89b12b46 autofs4: clean ->... |
35 |
static void autofs4_dentry_release(struct dentry *); |
1da177e4c Linux-2.6.12-rc2 |
36 |
|
4b6f5d20b [PATCH] Make most... |
37 |
const struct file_operations autofs4_root_operations = { |
1da177e4c Linux-2.6.12-rc2 |
38 39 40 |
.open = dcache_dir_open, .release = dcache_dir_close, .read = generic_read_dir, |
4e82901cd dcache_{readdir,d... |
41 |
.iterate_shared = dcache_readdir, |
59af1584b [PATCH] fix ->lls... |
42 |
.llseek = dcache_dir_lseek, |
3663df70c autofs4: Pushdown... |
43 |
.unlocked_ioctl = autofs4_root_ioctl, |
c9243f5bd autofs/autofs4: M... |
44 45 46 |
#ifdef CONFIG_COMPAT .compat_ioctl = autofs4_root_compat_ioctl, #endif |
1da177e4c Linux-2.6.12-rc2 |
47 |
}; |
4b6f5d20b [PATCH] Make most... |
48 |
const struct file_operations autofs4_dir_operations = { |
1da177e4c Linux-2.6.12-rc2 |
49 |
.open = autofs4_dir_open, |
ff9cd499d autofs4: cleanup ... |
50 |
.release = dcache_dir_close, |
1da177e4c Linux-2.6.12-rc2 |
51 |
.read = generic_read_dir, |
4e82901cd dcache_{readdir,d... |
52 |
.iterate_shared = dcache_readdir, |
59af1584b [PATCH] fix ->lls... |
53 |
.llseek = dcache_dir_lseek, |
1da177e4c Linux-2.6.12-rc2 |
54 |
}; |
754661f14 [PATCH] mark stru... |
55 |
const struct inode_operations autofs4_dir_inode_operations = { |
1da177e4c Linux-2.6.12-rc2 |
56 57 58 59 60 61 |
.lookup = autofs4_lookup, .unlink = autofs4_dir_unlink, .symlink = autofs4_dir_symlink, .mkdir = autofs4_dir_mkdir, .rmdir = autofs4_dir_rmdir, }; |
71e469db2 autofs4: Clean up... |
62 |
const struct dentry_operations autofs4_dentry_operations = { |
71e469db2 autofs4: Clean up... |
63 64 65 66 |
.d_automount = autofs4_d_automount, .d_manage = autofs4_d_manage, .d_release = autofs4_dentry_release, }; |
4f8427d19 autofs4: use help... |
67 68 69 |
static void autofs4_add_active(struct dentry *dentry) { struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); |
e9a7c2f1a autofs4: coding s... |
70 71 72 |
struct autofs_info *ino; ino = autofs4_dentry_ino(dentry); |
4f8427d19 autofs4: use help... |
73 74 75 76 77 78 79 80 81 |
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); } |
4f8427d19 autofs4: use help... |
82 83 84 85 86 |
} static void autofs4_del_active(struct dentry *dentry) { struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); |
e9a7c2f1a autofs4: coding s... |
87 88 89 |
struct autofs_info *ino; ino = autofs4_dentry_ino(dentry); |
4f8427d19 autofs4: use help... |
90 91 92 93 94 95 96 97 98 |
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); } |
4f8427d19 autofs4: use help... |
99 |
} |
1da177e4c Linux-2.6.12-rc2 |
100 101 |
static int autofs4_dir_open(struct inode *inode, struct file *file) { |
a4669ed8e [PATCH] autofs4: ... |
102 |
struct dentry *dentry = file->f_path.dentry; |
1da177e4c Linux-2.6.12-rc2 |
103 |
struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); |
f360ce3be [PATCH] autofs4: ... |
104 |
|
8a78d5930 autofs4: use pr_x... |
105 106 |
pr_debug("file=%p dentry=%p %pd ", file, dentry, dentry); |
1da177e4c Linux-2.6.12-rc2 |
107 108 109 |
if (autofs4_oz_mode(sbi)) goto out; |
ff9cd499d 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 autofs4 - remove ... |
119 |
spin_lock(&sbi->lookup_lock); |
0259cb02c autofs4 - use sim... |
120 |
if (!d_mountpoint(dentry) && simple_empty(dentry)) { |
e7854723d autofs4 - remove ... |
121 |
spin_unlock(&sbi->lookup_lock); |
ff9cd499d autofs4: cleanup ... |
122 |
return -ENOENT; |
1da177e4c Linux-2.6.12-rc2 |
123 |
} |
e7854723d autofs4 - remove ... |
124 |
spin_unlock(&sbi->lookup_lock); |
1da177e4c Linux-2.6.12-rc2 |
125 |
|
1da177e4c Linux-2.6.12-rc2 |
126 |
out: |
ff9cd499d autofs4: cleanup ... |
127 |
return dcache_dir_open(inode, file); |
1da177e4c Linux-2.6.12-rc2 |
128 |
} |
b89b12b46 autofs4: clean ->... |
129 |
static void autofs4_dentry_release(struct dentry *de) |
1da177e4c Linux-2.6.12-rc2 |
130 |
{ |
b89b12b46 autofs4: clean ->... |
131 132 |
struct autofs_info *ino = autofs4_dentry_ino(de); struct autofs_sb_info *sbi = autofs4_sbi(de->d_sb); |
1da177e4c Linux-2.6.12-rc2 |
133 |
|
8a78d5930 autofs4: use pr_x... |
134 135 |
pr_debug("releasing %p ", de); |
1da177e4c Linux-2.6.12-rc2 |
136 |
|
b89b12b46 autofs4: clean ->... |
137 138 139 140 141 142 143 144 145 146 |
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 Linux-2.6.12-rc2 |
147 |
} |
b89b12b46 autofs4: clean ->... |
148 149 |
autofs4_free_ino(ino); |
1da177e4c Linux-2.6.12-rc2 |
150 |
} |
6510c9d85 autofs4: cleanup ... |
151 |
static struct dentry *autofs4_lookup_active(struct dentry *dentry) |
257673787 autofs4: use look... |
152 |
{ |
6510c9d85 autofs4: cleanup ... |
153 154 |
struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); struct dentry *parent = dentry->d_parent; |
8ac790f31 qstr: constify in... |
155 |
const struct qstr *name = &dentry->d_name; |
257673787 autofs4: use look... |
156 157 158 159 |
unsigned int len = name->len; unsigned int hash = name->hash; const unsigned char *str = name->name; struct list_head *p, *head; |
257673787 autofs4: use look... |
160 |
head = &sbi->active_list; |
668128e90 autofs4: don't ta... |
161 162 163 |
if (list_empty(head)) return NULL; spin_lock(&sbi->lookup_lock); |
257673787 autofs4: use look... |
164 165 |
list_for_each(p, head) { struct autofs_info *ino; |
e4d5ade7b autofs4: rename d... |
166 |
struct dentry *active; |
8ac790f31 qstr: constify in... |
167 |
const struct qstr *qstr; |
257673787 autofs4: use look... |
168 169 |
ino = list_entry(p, struct autofs_info, active); |
e4d5ade7b autofs4: rename d... |
170 |
active = ino->dentry; |
257673787 autofs4: use look... |
171 |
|
e4d5ade7b autofs4: rename d... |
172 |
spin_lock(&active->d_lock); |
257673787 autofs4: use look... |
173 174 |
/* Already gone? */ |
6b6751f7f autofs: fix lockr... |
175 |
if ((int) d_count(active) <= 0) |
257673787 autofs4: use look... |
176 |
goto next; |
e4d5ade7b autofs4: rename d... |
177 |
qstr = &active->d_name; |
257673787 autofs4: use look... |
178 |
|
e4d5ade7b autofs4: rename d... |
179 |
if (active->d_name.hash != hash) |
257673787 autofs4: use look... |
180 |
goto next; |
e4d5ade7b autofs4: rename d... |
181 |
if (active->d_parent != parent) |
257673787 autofs4: use look... |
182 183 184 185 186 187 |
goto next; if (qstr->len != len) goto next; if (memcmp(qstr->name, str, len)) goto next; |
4b1ae27a9 Revert "autofs4: ... |
188 |
if (d_unhashed(active)) { |
b7ab39f63 fs: dcache scale ... |
189 |
dget_dlock(active); |
4b1ae27a9 Revert "autofs4: ... |
190 191 |
spin_unlock(&active->d_lock); spin_unlock(&sbi->lookup_lock); |
4b1ae27a9 Revert "autofs4: ... |
192 193 |
return active; } |
257673787 autofs4: use look... |
194 |
next: |
e4d5ade7b autofs4: rename d... |
195 |
spin_unlock(&active->d_lock); |
257673787 autofs4: use look... |
196 197 |
} spin_unlock(&sbi->lookup_lock); |
257673787 autofs4: use look... |
198 199 200 |
return NULL; } |
23bfc2a24 autofs4: allow RC... |
201 202 |
static struct dentry *autofs4_lookup_expiring(struct dentry *dentry, bool rcu_walk) |
f50b6f869 [PATCH] autofs4: ... |
203 |
{ |
6510c9d85 autofs4: cleanup ... |
204 205 |
struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); struct dentry *parent = dentry->d_parent; |
8ac790f31 qstr: constify in... |
206 |
const struct qstr *name = &dentry->d_name; |
f50b6f869 [PATCH] autofs4: ... |
207 208 209 210 |
unsigned int len = name->len; unsigned int hash = name->hash; const unsigned char *str = name->name; struct list_head *p, *head; |
5f6f4f28b autofs4: don't ma... |
211 |
head = &sbi->expiring_list; |
668128e90 autofs4: don't ta... |
212 213 214 |
if (list_empty(head)) return NULL; spin_lock(&sbi->lookup_lock); |
f50b6f869 [PATCH] autofs4: ... |
215 216 |
list_for_each(p, head) { struct autofs_info *ino; |
cb4b492ac autofs4: rename d... |
217 |
struct dentry *expiring; |
8ac790f31 qstr: constify in... |
218 |
const struct qstr *qstr; |
f50b6f869 [PATCH] autofs4: ... |
219 |
|
23bfc2a24 autofs4: allow RC... |
220 221 222 223 |
if (rcu_walk) { spin_unlock(&sbi->lookup_lock); return ERR_PTR(-ECHILD); } |
5f6f4f28b autofs4: don't ma... |
224 |
ino = list_entry(p, struct autofs_info, expiring); |
cb4b492ac autofs4: rename d... |
225 |
expiring = ino->dentry; |
f50b6f869 [PATCH] autofs4: ... |
226 |
|
cb4b492ac autofs4: rename d... |
227 |
spin_lock(&expiring->d_lock); |
f50b6f869 [PATCH] autofs4: ... |
228 |
|
6b6751f7f autofs: fix lockr... |
229 |
/* We've already been dentry_iput or unlinked */ |
2b0143b5c VFS: normal files... |
230 |
if (d_really_is_negative(expiring)) |
f50b6f869 [PATCH] autofs4: ... |
231 |
goto next; |
cb4b492ac autofs4: rename d... |
232 |
qstr = &expiring->d_name; |
f50b6f869 [PATCH] autofs4: ... |
233 |
|
cb4b492ac autofs4: rename d... |
234 |
if (expiring->d_name.hash != hash) |
f50b6f869 [PATCH] autofs4: ... |
235 |
goto next; |
cb4b492ac autofs4: rename d... |
236 |
if (expiring->d_parent != parent) |
f50b6f869 [PATCH] autofs4: ... |
237 238 239 240 241 242 |
goto next; if (qstr->len != len) goto next; if (memcmp(qstr->name, str, len)) goto next; |
4b1ae27a9 Revert "autofs4: ... |
243 |
if (d_unhashed(expiring)) { |
b7ab39f63 fs: dcache scale ... |
244 |
dget_dlock(expiring); |
4b1ae27a9 Revert "autofs4: ... |
245 246 |
spin_unlock(&expiring->d_lock); spin_unlock(&sbi->lookup_lock); |
4b1ae27a9 Revert "autofs4: ... |
247 248 |
return expiring; } |
f50b6f869 [PATCH] autofs4: ... |
249 |
next: |
cb4b492ac autofs4: rename d... |
250 |
spin_unlock(&expiring->d_lock); |
f50b6f869 [PATCH] autofs4: ... |
251 |
} |
5f6f4f28b autofs4: don't ma... |
252 |
spin_unlock(&sbi->lookup_lock); |
f50b6f869 [PATCH] autofs4: ... |
253 254 255 |
return NULL; } |
23bfc2a24 autofs4: allow RC... |
256 |
static int autofs4_mount_wait(struct dentry *dentry, bool rcu_walk) |
10584211e autofs4: Add d_au... |
257 258 259 |
{ struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); struct autofs_info *ino = autofs4_dentry_ino(dentry); |
3c3199852 autofs4 - reinsta... |
260 |
int status = 0; |
10584211e autofs4: Add d_au... |
261 262 |
if (ino->flags & AUTOFS_INF_PENDING) { |
23bfc2a24 autofs4: allow RC... |
263 264 |
if (rcu_walk) return -ECHILD; |
8a78d5930 autofs4: use pr_x... |
265 266 |
pr_debug("waiting for mount name=%pd ", dentry); |
10584211e autofs4: Add d_au... |
267 |
status = autofs4_wait(sbi, dentry, NFY_MOUNT); |
8a78d5930 autofs4: use pr_x... |
268 269 |
pr_debug("mount wait done status=%d ", status); |
10584211e autofs4: Add d_au... |
270 |
} |
3c3199852 autofs4 - reinsta... |
271 272 |
ino->last_used = jiffies; return status; |
10584211e autofs4: Add d_au... |
273 |
} |
23bfc2a24 autofs4: allow RC... |
274 |
static int do_expire_wait(struct dentry *dentry, bool rcu_walk) |
10584211e autofs4: Add d_au... |
275 276 |
{ struct dentry *expiring; |
23bfc2a24 autofs4: allow RC... |
277 278 279 |
expiring = autofs4_lookup_expiring(dentry, rcu_walk); if (IS_ERR(expiring)) return PTR_ERR(expiring); |
10584211e autofs4: Add d_au... |
280 |
if (!expiring) |
23bfc2a24 autofs4: allow RC... |
281 |
return autofs4_expire_wait(dentry, rcu_walk); |
10584211e autofs4: Add d_au... |
282 283 284 285 286 287 |
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. */ |
23bfc2a24 autofs4: allow RC... |
288 |
autofs4_expire_wait(expiring, 0); |
10584211e autofs4: Add d_au... |
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 |
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 autofs4 - reinsta... |
306 |
struct autofs_info *ino; |
e9a7c2f1a autofs4: coding s... |
307 308 309 |
struct dentry *new; new = d_lookup(parent, &dentry->d_name); |
10584211e autofs4: Add d_au... |
310 311 |
if (!new) return NULL; |
3c3199852 autofs4 - reinsta... |
312 313 |
ino = autofs4_dentry_ino(new); ino->last_used = jiffies; |
10584211e autofs4: Add d_au... |
314 315 316 317 318 |
dput(path->dentry); path->dentry = new; } return path->dentry; } |
71e469db2 autofs4: Clean up... |
319 |
static struct vfsmount *autofs4_d_automount(struct path *path) |
10584211e autofs4: Add d_au... |
320 321 322 323 324 |
{ 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; |
8a78d5930 autofs4: use pr_x... |
325 326 |
pr_debug("dentry=%p %pd ", dentry, dentry); |
10584211e autofs4: Add d_au... |
327 328 329 330 331 332 333 334 335 336 337 338 339 |
/* 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. */ |
23bfc2a24 autofs4: allow RC... |
340 |
status = do_expire_wait(dentry, 0); |
10584211e autofs4: Add d_au... |
341 342 343 344 345 346 347 |
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); |
23bfc2a24 autofs4: allow RC... |
348 |
status = autofs4_mount_wait(dentry, 0); |
10584211e autofs4: Add d_au... |
349 350 |
if (status) return ERR_PTR(status); |
10584211e autofs4: Add d_au... |
351 352 353 354 355 |
goto done; } /* * If the dentry is a symlink it's equivalent to a directory |
b5b801779 autofs4: Add d_ma... |
356 |
* having d_mountpoint() true, so there's no need to call back |
10584211e autofs4: Add d_au... |
357 358 |
* to the daemon. */ |
2b0143b5c VFS: normal files... |
359 |
if (d_really_is_positive(dentry) && d_is_symlink(dentry)) { |
f55fb0c24 autofs4 - dont cl... |
360 |
spin_unlock(&sbi->fs_lock); |
10584211e autofs4: Add d_au... |
361 |
goto done; |
f55fb0c24 autofs4 - dont cl... |
362 |
} |
b5b801779 autofs4: Add d_ma... |
363 364 365 366 367 368 369 370 |
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 |
3b97dd058 autofs4: comment ... |
371 |
* do need the leaves to trigger mounts. In this case we |
b5b801779 autofs4: Add d_ma... |
372 373 374 375 |
* have no choice but to use the list_empty() check and * require user space behave. */ if (sbi->version > 4) { |
f55fb0c24 autofs4 - dont cl... |
376 377 |
if (have_submounts(dentry)) { spin_unlock(&sbi->fs_lock); |
b5b801779 autofs4: Add d_ma... |
378 |
goto done; |
f55fb0c24 autofs4 - dont cl... |
379 |
} |
b5b801779 autofs4: Add d_ma... |
380 |
} else { |
9d8072e7c autofs - Fix spar... |
381 382 |
if (!simple_empty(dentry)) { spin_unlock(&sbi->fs_lock); |
b5b801779 autofs4: Add d_ma... |
383 |
goto done; |
9d8072e7c autofs - Fix spar... |
384 |
} |
b5b801779 autofs4: Add d_ma... |
385 |
} |
10584211e autofs4: Add d_au... |
386 |
ino->flags |= AUTOFS_INF_PENDING; |
10584211e autofs4: Add d_au... |
387 |
spin_unlock(&sbi->fs_lock); |
23bfc2a24 autofs4: allow RC... |
388 |
status = autofs4_mount_wait(dentry, 0); |
10584211e autofs4: Add d_au... |
389 390 |
spin_lock(&sbi->fs_lock); ino->flags &= ~AUTOFS_INF_PENDING; |
49999ab27 autofs4 - fix res... |
391 392 393 394 |
if (status) { spin_unlock(&sbi->fs_lock); return ERR_PTR(status); } |
10584211e autofs4: Add d_au... |
395 |
} |
10584211e autofs4: Add d_au... |
396 |
spin_unlock(&sbi->fs_lock); |
f55fb0c24 autofs4 - dont cl... |
397 |
done: |
10584211e autofs4: Add d_au... |
398 399 400 401 402 403 404 |
/* Mount succeeded, check if we ended up with a new dentry */ dentry = autofs4_mountpoint_changed(path); if (!dentry) return ERR_PTR(-ENOENT); return NULL; } |
954829863 autofs - fix spar... |
405 |
static int autofs4_d_manage(struct dentry *dentry, bool rcu_walk) |
b5b801779 autofs4: Add d_ma... |
406 407 |
{ struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); |
f55fb0c24 autofs4 - dont cl... |
408 409 |
struct autofs_info *ino = autofs4_dentry_ino(dentry); int status; |
b5b801779 autofs4: Add d_ma... |
410 |
|
8a78d5930 autofs4: use pr_x... |
411 412 |
pr_debug("dentry=%p %pd ", dentry, dentry); |
b5b801779 autofs4: Add d_ma... |
413 414 |
/* The daemon never waits. */ |
1aed3e420 lose 'mounting_he... |
415 |
if (autofs4_oz_mode(sbi)) { |
b5b801779 autofs4: Add d_ma... |
416 417 418 419 420 421 |
if (!d_mountpoint(dentry)) return -EISDIR; return 0; } /* Wait for pending expires */ |
23bfc2a24 autofs4: allow RC... |
422 423 |
if (do_expire_wait(dentry, rcu_walk) == -ECHILD) return -ECHILD; |
b5b801779 autofs4: Add d_ma... |
424 425 426 427 428 |
/* * This dentry may be under construction so wait on mount * completion. */ |
23bfc2a24 autofs4: allow RC... |
429 |
status = autofs4_mount_wait(dentry, rcu_walk); |
f55fb0c24 autofs4 - dont cl... |
430 431 |
if (status) return status; |
ef16cc590 autofs4: d_manage... |
432 433 434 435 436 437 438 |
if (rcu_walk) { /* We don't need fs_lock in rcu_walk mode, * just testing 'AUTOFS_INFO_NO_RCU' is enough. * simple_empty() takes a spinlock, so leave it * to last. * We only return -EISDIR when certain this isn't * a mount-trap. |
23bfc2a24 autofs4: allow RC... |
439 |
*/ |
ef16cc590 autofs4: d_manage... |
440 |
struct inode *inode; |
e9a7c2f1a autofs4: coding s... |
441 |
|
ea01a1849 autofs races |
442 |
if (ino->flags & AUTOFS_INF_WANT_EXPIRE) |
ef16cc590 autofs4: d_manage... |
443 444 445 |
return 0; if (d_mountpoint(dentry)) return 0; |
2b0143b5c VFS: normal files... |
446 |
inode = d_inode_rcu(dentry); |
ef16cc590 autofs4: d_manage... |
447 448 449 450 451 452 |
if (inode && S_ISLNK(inode->i_mode)) return -EISDIR; if (list_empty(&dentry->d_subdirs)) return 0; if (!simple_empty(dentry)) return -EISDIR; |
23bfc2a24 autofs4: allow RC... |
453 |
return 0; |
ef16cc590 autofs4: d_manage... |
454 |
} |
23bfc2a24 autofs4: allow RC... |
455 |
|
f55fb0c24 autofs4 - dont cl... |
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 |
spin_lock(&sbi->fs_lock); /* * If the dentry has been selected for expire while we slept * on the lock then it might go away. We'll deal with that in * ->d_automount() and wait on a new mount if the expire * succeeds or return here if it doesn't (since there's no * mount to follow with a rootless multi-mount). */ if (!(ino->flags & AUTOFS_INF_EXPIRING)) { /* * Any needed mounting has been completed and the path * updated so check if this is a rootless multi-mount so * we can avoid needless calls ->d_automount() and avoid * an incorrect ELOOP error return. */ if ((!d_mountpoint(dentry) && !simple_empty(dentry)) || |
2b0143b5c VFS: normal files... |
472 |
(d_really_is_positive(dentry) && d_is_symlink(dentry))) |
f55fb0c24 autofs4 - dont cl... |
473 474 475 476 477 |
status = -EISDIR; } spin_unlock(&sbi->fs_lock); return status; |
b5b801779 autofs4: Add d_ma... |
478 |
} |
1da177e4c Linux-2.6.12-rc2 |
479 |
/* Lookups in the root directory */ |
e9a7c2f1a autofs4: coding s... |
480 481 |
static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) |
1da177e4c Linux-2.6.12-rc2 |
482 483 |
{ struct autofs_sb_info *sbi; |
257673787 autofs4: use look... |
484 |
struct autofs_info *ino; |
10584211e autofs4: Add d_au... |
485 |
struct dentry *active; |
1da177e4c Linux-2.6.12-rc2 |
486 |
|
8a78d5930 autofs4: use pr_x... |
487 488 |
pr_debug("name = %pd ", dentry); |
1da177e4c Linux-2.6.12-rc2 |
489 |
|
718c604a2 [PATCH] autofs4: ... |
490 |
/* File name too long to exist */ |
1da177e4c Linux-2.6.12-rc2 |
491 |
if (dentry->d_name.len > NAME_MAX) |
718c604a2 [PATCH] autofs4: ... |
492 |
return ERR_PTR(-ENAMETOOLONG); |
1da177e4c Linux-2.6.12-rc2 |
493 494 |
sbi = autofs4_sbi(dir->i_sb); |
718c604a2 [PATCH] autofs4: ... |
495 |
|
8a78d5930 autofs4: use pr_x... |
496 497 498 499 |
pr_debug("pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d ", current->pid, task_pgrp_nr(current), sbi->catatonic, autofs4_oz_mode(sbi)); |
1da177e4c Linux-2.6.12-rc2 |
500 |
|
6510c9d85 autofs4: cleanup ... |
501 |
active = autofs4_lookup_active(dentry); |
e9a7c2f1a autofs4: coding s... |
502 |
if (active) |
10584211e autofs4: Add d_au... |
503 |
return active; |
e9a7c2f1a autofs4: coding s... |
504 |
else { |
4b1ae27a9 Revert "autofs4: ... |
505 |
/* |
10584211e autofs4: Add d_au... |
506 507 508 509 |
* 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 Revert "autofs4: ... |
510 |
*/ |
10584211e autofs4: Add d_au... |
511 512 513 514 |
if (!autofs4_oz_mode(sbi) && !IS_ROOT(dentry->d_parent)) return ERR_PTR(-ENOENT); /* Mark entries in the root as mount triggers */ |
e9a7c2f1a autofs4: coding s... |
515 516 |
if (IS_ROOT(dentry->d_parent) && autofs_type_indirect(sbi->type)) |
b5b801779 autofs4: Add d_ma... |
517 |
__managed_dentry_set_managed(dentry); |
10584211e autofs4: Add d_au... |
518 |
|
26e6c9106 autofs4: split au... |
519 |
ino = autofs4_new_ino(sbi); |
4b1ae27a9 Revert "autofs4: ... |
520 521 522 523 524 |
if (!ino) return ERR_PTR(-ENOMEM); dentry->d_fsdata = ino; ino->dentry = dentry; |
5f6f4f28b autofs4: don't ma... |
525 |
|
4b1ae27a9 Revert "autofs4: ... |
526 |
autofs4_add_active(dentry); |
4b1ae27a9 Revert "autofs4: ... |
527 |
} |
1da177e4c Linux-2.6.12-rc2 |
528 529 530 531 532 533 534 535 536 |
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 [PATCH] autofs4: ... |
537 |
struct autofs_info *p_ino; |
1da177e4c Linux-2.6.12-rc2 |
538 |
struct inode *inode; |
0bf71d4d0 autofs4: kill ->s... |
539 |
size_t size = strlen(symname); |
1da177e4c Linux-2.6.12-rc2 |
540 |
char *cp; |
8a78d5930 autofs4: use pr_x... |
541 542 |
pr_debug("%s <- %pd ", symname, dentry); |
1da177e4c Linux-2.6.12-rc2 |
543 544 545 |
if (!autofs4_oz_mode(sbi)) return -EACCES; |
5a37db302 autofs4: mkdir an... |
546 |
BUG_ON(!ino); |
26e6c9106 autofs4: split au... |
547 |
autofs4_clean_ino(ino); |
1da177e4c Linux-2.6.12-rc2 |
548 |
|
4b1ae27a9 Revert "autofs4: ... |
549 |
autofs4_del_active(dentry); |
0bf71d4d0 autofs4: kill ->s... |
550 |
cp = kmalloc(size + 1, GFP_KERNEL); |
5a37db302 autofs4: mkdir an... |
551 |
if (!cp) |
257673787 autofs4: use look... |
552 |
return -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
553 554 |
strcpy(cp, symname); |
726a5e068 autofs4: autofs4_... |
555 |
inode = autofs4_get_inode(dir->i_sb, S_IFLNK | 0555); |
257673787 autofs4: use look... |
556 557 |
if (!inode) { kfree(cp); |
257673787 autofs4: use look... |
558 559 |
return -ENOMEM; } |
292c5ee80 autofs4: keep sym... |
560 |
inode->i_private = cp; |
0bf71d4d0 autofs4: kill ->s... |
561 |
inode->i_size = size; |
1864f7bd5 autofs4: deadlock... |
562 |
d_add(dentry, inode); |
1da177e4c Linux-2.6.12-rc2 |
563 |
|
5a37db302 autofs4: mkdir an... |
564 |
dget(dentry); |
1aff3c8b0 [PATCH] autofs4: ... |
565 566 |
atomic_inc(&ino->count); p_ino = autofs4_dentry_ino(dentry->d_parent); |
c24930a9b autofs: use IS_RO... |
567 |
if (p_ino && !IS_ROOT(dentry)) |
1aff3c8b0 [PATCH] autofs4: ... |
568 |
atomic_inc(&p_ino->count); |
1da177e4c Linux-2.6.12-rc2 |
569 |
|
078cd8279 fs: Replace CURRE... |
570 |
dir->i_mtime = current_time(dir); |
1da177e4c Linux-2.6.12-rc2 |
571 572 573 574 575 576 577 578 579 580 |
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 [PATCH] autofs4: ... |
581 |
* this, because the unlink is probably the result of an expire. |
5f6f4f28b autofs4: don't ma... |
582 583 |
* 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 Linux-2.6.12-rc2 |
584 585 586 587 588 589 590 591 592 593 |
* * 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 [PATCH] autofs4: ... |
594 |
struct autofs_info *p_ino; |
0266725ad autofs4: fix some... |
595 |
|
1da177e4c Linux-2.6.12-rc2 |
596 |
/* This allows root to remove symlinks */ |
d78e53c89 Fix some coding-s... |
597 |
if (!autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN)) |
417358187 fs: change return... |
598 |
return -EPERM; |
1da177e4c Linux-2.6.12-rc2 |
599 |
|
1aff3c8b0 [PATCH] autofs4: ... |
600 601 |
if (atomic_dec_and_test(&ino->count)) { p_ino = autofs4_dentry_ino(dentry->d_parent); |
c24930a9b autofs: use IS_RO... |
602 |
if (p_ino && !IS_ROOT(dentry)) |
1aff3c8b0 [PATCH] autofs4: ... |
603 604 |
atomic_dec(&p_ino->count); } |
1da177e4c Linux-2.6.12-rc2 |
605 |
dput(ino->dentry); |
2b0143b5c VFS: normal files... |
606 607 |
d_inode(dentry)->i_size = 0; clear_nlink(d_inode(dentry)); |
1da177e4c Linux-2.6.12-rc2 |
608 |
|
078cd8279 fs: Replace CURRE... |
609 |
dir->i_mtime = current_time(dir); |
1da177e4c Linux-2.6.12-rc2 |
610 |
|
e7854723d autofs4 - remove ... |
611 612 |
spin_lock(&sbi->lookup_lock); __autofs4_add_expiring(dentry); |
0259cb02c autofs4 - use sim... |
613 |
d_drop(dentry); |
e7854723d autofs4 - remove ... |
614 |
spin_unlock(&sbi->lookup_lock); |
1da177e4c Linux-2.6.12-rc2 |
615 616 617 |
return 0; } |
dd89f90d2 autofs4: Add v4 p... |
618 619 620 621 622 623 624 |
/* * 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 Fix common misspe... |
625 |
* are always covered. However, it is necessary to ensure that these |
dd89f90d2 autofs4: Add v4 p... |
626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 |
* 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); |
dd89f90d2 autofs4: Add v4 p... |
644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 |
} 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; |
946e51f2b move d_rcu from o... |
661 |
d_child = &dentry->d_child; |
dd89f90d2 autofs4: Add v4 p... |
662 663 664 665 |
/* 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); |
dd89f90d2 autofs4: Add v4 p... |
666 |
} |
1da177e4c Linux-2.6.12-rc2 |
667 668 669 670 |
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 [PATCH] autofs4: ... |
671 |
struct autofs_info *p_ino; |
0266725ad autofs4: fix some... |
672 |
|
8a78d5930 autofs4: use pr_x... |
673 674 |
pr_debug("dentry %p, removing %pd ", dentry, dentry); |
f50b6f869 [PATCH] autofs4: ... |
675 |
|
1da177e4c Linux-2.6.12-rc2 |
676 677 |
if (!autofs4_oz_mode(sbi)) return -EACCES; |
2fd6b7f50 fs: dcache scale ... |
678 |
spin_lock(&sbi->lookup_lock); |
0259cb02c autofs4 - use sim... |
679 |
if (!simple_empty(dentry)) { |
2fd6b7f50 fs: dcache scale ... |
680 |
spin_unlock(&sbi->lookup_lock); |
1da177e4c Linux-2.6.12-rc2 |
681 682 |
return -ENOTEMPTY; } |
2fd6b7f50 fs: dcache scale ... |
683 |
__autofs4_add_expiring(dentry); |
0259cb02c autofs4 - use sim... |
684 |
d_drop(dentry); |
e7854723d autofs4 - remove ... |
685 |
spin_unlock(&sbi->lookup_lock); |
1da177e4c Linux-2.6.12-rc2 |
686 |
|
dd89f90d2 autofs4: Add v4 p... |
687 688 |
if (sbi->version < 5) autofs_clear_leaf_automount_flags(dentry); |
1aff3c8b0 [PATCH] autofs4: ... |
689 690 691 692 693 |
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 Linux-2.6.12-rc2 |
694 |
dput(ino->dentry); |
2b0143b5c VFS: normal files... |
695 696 |
d_inode(dentry)->i_size = 0; clear_nlink(d_inode(dentry)); |
1da177e4c Linux-2.6.12-rc2 |
697 698 |
if (dir->i_nlink) |
9a53c3a78 [PATCH] r/o bind ... |
699 |
drop_nlink(dir); |
1da177e4c Linux-2.6.12-rc2 |
700 701 702 |
return 0; } |
e9a7c2f1a autofs4: coding s... |
703 704 |
static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) |
1da177e4c Linux-2.6.12-rc2 |
705 706 707 |
{ struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb); struct autofs_info *ino = autofs4_dentry_ino(dentry); |
1aff3c8b0 [PATCH] autofs4: ... |
708 |
struct autofs_info *p_ino; |
1da177e4c Linux-2.6.12-rc2 |
709 |
struct inode *inode; |
d78e53c89 Fix some coding-s... |
710 |
if (!autofs4_oz_mode(sbi)) |
1da177e4c Linux-2.6.12-rc2 |
711 |
return -EACCES; |
8a78d5930 autofs4: use pr_x... |
712 713 |
pr_debug("dentry %p, creating %pd ", dentry, dentry); |
1da177e4c Linux-2.6.12-rc2 |
714 |
|
5a37db302 autofs4: mkdir an... |
715 |
BUG_ON(!ino); |
26e6c9106 autofs4: split au... |
716 |
autofs4_clean_ino(ino); |
257673787 autofs4: use look... |
717 |
|
4b1ae27a9 Revert "autofs4: ... |
718 |
autofs4_del_active(dentry); |
726a5e068 autofs4: autofs4_... |
719 |
inode = autofs4_get_inode(dir->i_sb, S_IFDIR | 0555); |
5a37db302 autofs4: mkdir an... |
720 |
if (!inode) |
257673787 autofs4: use look... |
721 |
return -ENOMEM; |
1864f7bd5 autofs4: deadlock... |
722 |
d_add(dentry, inode); |
1da177e4c Linux-2.6.12-rc2 |
723 |
|
dd89f90d2 autofs4: Add v4 p... |
724 725 |
if (sbi->version < 5) autofs_set_leaf_automount_flags(dentry); |
5a37db302 autofs4: mkdir an... |
726 |
dget(dentry); |
1aff3c8b0 [PATCH] autofs4: ... |
727 728 |
atomic_inc(&ino->count); p_ino = autofs4_dentry_ino(dentry->d_parent); |
c24930a9b autofs: use IS_RO... |
729 |
if (p_ino && !IS_ROOT(dentry)) |
1aff3c8b0 [PATCH] autofs4: ... |
730 |
atomic_inc(&p_ino->count); |
d8c76e6f4 [PATCH] r/o bind ... |
731 |
inc_nlink(dir); |
078cd8279 fs: Replace CURRE... |
732 |
dir->i_mtime = current_time(dir); |
1da177e4c Linux-2.6.12-rc2 |
733 734 735 736 737 |
return 0; } /* Get/set timeout ioctl() operation */ |
c9243f5bd autofs/autofs4: M... |
738 739 |
#ifdef CONFIG_COMPAT static inline int autofs4_compat_get_set_timeout(struct autofs_sb_info *sbi, |
e9a7c2f1a autofs4: coding s... |
740 |
compat_ulong_t __user *p) |
c9243f5bd autofs/autofs4: M... |
741 |
{ |
c9243f5bd autofs/autofs4: M... |
742 |
unsigned long ntimeout; |
aa330ddc5 autofs4: fix codi... |
743 744 745 746 747 |
int rv; rv = get_user(ntimeout, p); if (rv) goto error; |
c9243f5bd autofs/autofs4: M... |
748 |
|
aa330ddc5 autofs4: fix codi... |
749 750 751 |
rv = put_user(sbi->exp_timeout/HZ, p); if (rv) goto error; |
c9243f5bd autofs/autofs4: M... |
752 753 754 755 756 757 758 |
if (ntimeout > UINT_MAX/HZ) sbi->exp_timeout = 0; else sbi->exp_timeout = ntimeout * HZ; return 0; |
aa330ddc5 autofs4: fix codi... |
759 760 |
error: return rv; |
c9243f5bd autofs/autofs4: M... |
761 762 |
} #endif |
1da177e4c Linux-2.6.12-rc2 |
763 |
static inline int autofs4_get_set_timeout(struct autofs_sb_info *sbi, |
e9a7c2f1a autofs4: coding s... |
764 |
unsigned long __user *p) |
1da177e4c Linux-2.6.12-rc2 |
765 |
{ |
1da177e4c Linux-2.6.12-rc2 |
766 |
unsigned long ntimeout; |
aa330ddc5 autofs4: fix codi... |
767 768 769 770 771 |
int rv; rv = get_user(ntimeout, p); if (rv) goto error; |
1da177e4c Linux-2.6.12-rc2 |
772 |
|
aa330ddc5 autofs4: fix codi... |
773 774 775 |
rv = put_user(sbi->exp_timeout/HZ, p); if (rv) goto error; |
1da177e4c Linux-2.6.12-rc2 |
776 |
|
d78e53c89 Fix some coding-s... |
777 |
if (ntimeout > ULONG_MAX/HZ) |
1da177e4c Linux-2.6.12-rc2 |
778 779 780 781 782 |
sbi->exp_timeout = 0; else sbi->exp_timeout = ntimeout * HZ; return 0; |
aa330ddc5 autofs4: fix codi... |
783 784 |
error: return rv; |
1da177e4c Linux-2.6.12-rc2 |
785 786 787 |
} /* Return protocol version */ |
e9a7c2f1a autofs4: coding s... |
788 789 |
static inline int autofs4_get_protover(struct autofs_sb_info *sbi, int __user *p) |
1da177e4c Linux-2.6.12-rc2 |
790 791 792 793 794 |
{ return put_user(sbi->version, p); } /* Return protocol sub version */ |
e9a7c2f1a autofs4: coding s... |
795 796 |
static inline int autofs4_get_protosubver(struct autofs_sb_info *sbi, int __user *p) |
1da177e4c Linux-2.6.12-rc2 |
797 798 799 800 801 |
{ return put_user(sbi->sub_version, p); } /* |
1da177e4c Linux-2.6.12-rc2 |
802 803 804 805 806 |
* 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 [PATCH] autofs4: ... |
807 |
if (may_umount(mnt)) |
1da177e4c Linux-2.6.12-rc2 |
808 |
status = 1; |
b6e3795a0 autofs: fix pr_de... |
809 810 |
pr_debug("may umount %d ", status); |
1da177e4c Linux-2.6.12-rc2 |
811 812 813 814 815 816 817 |
status = put_user(status, p); return status; } /* Identify autofs4_dentries - this is so we can tell if there's |
e9a7c2f1a autofs4: coding s... |
818 819 820 |
* an extra dentry refcount or not. We only hold a refcount on the * dentry if its non-negative (ie, d_inode != NULL) */ |
1da177e4c Linux-2.6.12-rc2 |
821 822 |
int is_autofs4_dentry(struct dentry *dentry) { |
2b0143b5c VFS: normal files... |
823 |
return dentry && d_really_is_positive(dentry) && |
b650c858c autofs4: Merge th... |
824 |
dentry->d_op == &autofs4_dentry_operations && |
1da177e4c Linux-2.6.12-rc2 |
825 826 827 828 829 830 831 |
dentry->d_fsdata != NULL; } /* * ioctl()'s on the root directory is the chief method for the daemon to * generate kernel reactions */ |
3663df70c autofs4: Pushdown... |
832 833 |
static int autofs4_root_ioctl_unlocked(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) |
1da177e4c Linux-2.6.12-rc2 |
834 835 836 |
{ struct autofs_sb_info *sbi = autofs4_sbi(inode->i_sb); void __user *p = (void __user *)arg; |
8a78d5930 autofs4: use pr_x... |
837 838 839 |
pr_debug("cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u ", cmd, arg, sbi, task_pgrp_nr(current)); |
1da177e4c Linux-2.6.12-rc2 |
840 |
|
d78e53c89 Fix some coding-s... |
841 842 |
if (_IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) || _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT) |
1da177e4c Linux-2.6.12-rc2 |
843 |
return -ENOTTY; |
0266725ad autofs4: fix some... |
844 |
|
d78e53c89 Fix some coding-s... |
845 |
if (!autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN)) |
1da177e4c Linux-2.6.12-rc2 |
846 |
return -EPERM; |
0266725ad autofs4: fix some... |
847 |
|
e9a7c2f1a autofs4: coding s... |
848 |
switch (cmd) { |
1da177e4c Linux-2.6.12-rc2 |
849 |
case AUTOFS_IOC_READY: /* Wait queue: go ahead and retry */ |
e9a7c2f1a autofs4: coding s... |
850 |
return autofs4_wait_release(sbi, (autofs_wqt_t) arg, 0); |
1da177e4c Linux-2.6.12-rc2 |
851 |
case AUTOFS_IOC_FAIL: /* Wait queue: fail with ENOENT */ |
e9a7c2f1a autofs4: coding s... |
852 |
return autofs4_wait_release(sbi, (autofs_wqt_t) arg, -ENOENT); |
1da177e4c Linux-2.6.12-rc2 |
853 854 855 856 857 858 859 860 861 |
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 autofs/autofs4: M... |
862 863 864 865 |
#ifdef CONFIG_COMPAT case AUTOFS_IOC_SETTIMEOUT32: return autofs4_compat_get_set_timeout(sbi, p); #endif |
1da177e4c Linux-2.6.12-rc2 |
866 |
|
1da177e4c Linux-2.6.12-rc2 |
867 |
case AUTOFS_IOC_ASKUMOUNT: |
a4669ed8e [PATCH] autofs4: ... |
868 |
return autofs4_ask_umount(filp->f_path.mnt, p); |
1da177e4c Linux-2.6.12-rc2 |
869 870 871 |
/* return a single thing to expire */ case AUTOFS_IOC_EXPIRE: |
e9a7c2f1a autofs4: coding s... |
872 873 |
return autofs4_expire_run(inode->i_sb, filp->f_path.mnt, sbi, p); |
1da177e4c Linux-2.6.12-rc2 |
874 875 |
/* same as above, but can send multiple expires through pipe */ case AUTOFS_IOC_EXPIRE_MULTI: |
e9a7c2f1a autofs4: coding s... |
876 877 |
return autofs4_expire_multi(inode->i_sb, filp->f_path.mnt, sbi, p); |
1da177e4c Linux-2.6.12-rc2 |
878 879 |
default: |
e3cd8067c autofs4: fix inva... |
880 |
return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
881 882 |
} } |
3663df70c autofs4: Pushdown... |
883 884 885 886 |
static long autofs4_root_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { |
496ad9aa8 new helper: file_... |
887 |
struct inode *inode = file_inode(filp); |
e9a7c2f1a autofs4: coding s... |
888 |
|
de47de740 autofs4 - remove ... |
889 |
return autofs4_root_ioctl_unlocked(inode, filp, cmd, arg); |
3663df70c autofs4: Pushdown... |
890 |
} |
c9243f5bd autofs/autofs4: M... |
891 892 893 |
#ifdef CONFIG_COMPAT static long autofs4_root_compat_ioctl(struct file *filp, |
e9a7c2f1a autofs4: coding s... |
894 |
unsigned int cmd, unsigned long arg) |
c9243f5bd autofs/autofs4: M... |
895 |
{ |
496ad9aa8 new helper: file_... |
896 |
struct inode *inode = file_inode(filp); |
c9243f5bd autofs/autofs4: M... |
897 |
int ret; |
c9243f5bd autofs/autofs4: M... |
898 899 900 901 |
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, |
e9a7c2f1a autofs4: coding s... |
902 |
(unsigned long) compat_ptr(arg)); |
c9243f5bd autofs/autofs4: M... |
903 904 905 906 |
return ret; } #endif |