diff options
Diffstat (limited to 'fs/autofs4/root.c')
-rw-r--r-- | fs/autofs4/root.c | 743 |
1 files changed, 315 insertions, 428 deletions
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 651e4ef563b1..014e7aba3b08 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
@@ -35,10 +35,9 @@ static long autofs4_root_compat_ioctl(struct file *,unsigned int,unsigned long); | |||
35 | #endif | 35 | #endif |
36 | static int autofs4_dir_open(struct inode *inode, struct file *file); | 36 | static int autofs4_dir_open(struct inode *inode, struct file *file); |
37 | static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *); | 37 | static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *); |
38 | static void *autofs4_follow_link(struct dentry *, struct nameidata *); | 38 | static struct vfsmount *autofs4_d_automount(struct path *); |
39 | 39 | static int autofs4_d_manage(struct dentry *, bool, bool); | |
40 | #define TRIGGER_FLAGS (LOOKUP_CONTINUE | LOOKUP_DIRECTORY) | 40 | static void autofs4_dentry_release(struct dentry *); |
41 | #define TRIGGER_INTENTS (LOOKUP_OPEN | LOOKUP_CREATE) | ||
42 | 41 | ||
43 | const struct file_operations autofs4_root_operations = { | 42 | const struct file_operations autofs4_root_operations = { |
44 | .open = dcache_dir_open, | 43 | .open = dcache_dir_open, |
@@ -60,7 +59,7 @@ const struct file_operations autofs4_dir_operations = { | |||
60 | .llseek = dcache_dir_lseek, | 59 | .llseek = dcache_dir_lseek, |
61 | }; | 60 | }; |
62 | 61 | ||
63 | const struct inode_operations autofs4_indirect_root_inode_operations = { | 62 | const struct inode_operations autofs4_dir_inode_operations = { |
64 | .lookup = autofs4_lookup, | 63 | .lookup = autofs4_lookup, |
65 | .unlink = autofs4_dir_unlink, | 64 | .unlink = autofs4_dir_unlink, |
66 | .symlink = autofs4_dir_symlink, | 65 | .symlink = autofs4_dir_symlink, |
@@ -68,20 +67,10 @@ const struct inode_operations autofs4_indirect_root_inode_operations = { | |||
68 | .rmdir = autofs4_dir_rmdir, | 67 | .rmdir = autofs4_dir_rmdir, |
69 | }; | 68 | }; |
70 | 69 | ||
71 | const struct inode_operations autofs4_direct_root_inode_operations = { | 70 | const struct dentry_operations autofs4_dentry_operations = { |
72 | .lookup = autofs4_lookup, | 71 | .d_automount = autofs4_d_automount, |
73 | .unlink = autofs4_dir_unlink, | 72 | .d_manage = autofs4_d_manage, |
74 | .mkdir = autofs4_dir_mkdir, | 73 | .d_release = autofs4_dentry_release, |
75 | .rmdir = autofs4_dir_rmdir, | ||
76 | .follow_link = autofs4_follow_link, | ||
77 | }; | ||
78 | |||
79 | const struct inode_operations autofs4_dir_inode_operations = { | ||
80 | .lookup = autofs4_lookup, | ||
81 | .unlink = autofs4_dir_unlink, | ||
82 | .symlink = autofs4_dir_symlink, | ||
83 | .mkdir = autofs4_dir_mkdir, | ||
84 | .rmdir = autofs4_dir_rmdir, | ||
85 | }; | 74 | }; |
86 | 75 | ||
87 | static void autofs4_add_active(struct dentry *dentry) | 76 | static void autofs4_add_active(struct dentry *dentry) |
@@ -116,14 +105,6 @@ static void autofs4_del_active(struct dentry *dentry) | |||
116 | return; | 105 | return; |
117 | } | 106 | } |
118 | 107 | ||
119 | static unsigned int autofs4_need_mount(unsigned int flags) | ||
120 | { | ||
121 | unsigned int res = 0; | ||
122 | if (flags & (TRIGGER_FLAGS | TRIGGER_INTENTS)) | ||
123 | res = 1; | ||
124 | return res; | ||
125 | } | ||
126 | |||
127 | static int autofs4_dir_open(struct inode *inode, struct file *file) | 108 | static int autofs4_dir_open(struct inode *inode, struct file *file) |
128 | { | 109 | { |
129 | struct dentry *dentry = file->f_path.dentry; | 110 | struct dentry *dentry = file->f_path.dentry; |
@@ -158,278 +139,27 @@ out: | |||
158 | return dcache_dir_open(inode, file); | 139 | return dcache_dir_open(inode, file); |
159 | } | 140 | } |
160 | 141 | ||
161 | static int try_to_fill_dentry(struct dentry *dentry, int flags) | 142 | static void autofs4_dentry_release(struct dentry *de) |
162 | { | ||
163 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); | ||
164 | struct autofs_info *ino = autofs4_dentry_ino(dentry); | ||
165 | int status; | ||
166 | |||
167 | DPRINTK("dentry=%p %.*s ino=%p", | ||
168 | dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode); | ||
169 | |||
170 | /* | ||
171 | * Wait for a pending mount, triggering one if there | ||
172 | * isn't one already | ||
173 | */ | ||
174 | if (dentry->d_inode == NULL) { | ||
175 | DPRINTK("waiting for mount name=%.*s", | ||
176 | dentry->d_name.len, dentry->d_name.name); | ||
177 | |||
178 | status = autofs4_wait(sbi, dentry, NFY_MOUNT); | ||
179 | |||
180 | DPRINTK("mount done status=%d", status); | ||
181 | |||
182 | /* Turn this into a real negative dentry? */ | ||
183 | if (status == -ENOENT) { | ||
184 | spin_lock(&sbi->fs_lock); | ||
185 | ino->flags &= ~AUTOFS_INF_PENDING; | ||
186 | spin_unlock(&sbi->fs_lock); | ||
187 | return status; | ||
188 | } else if (status) { | ||
189 | /* Return a negative dentry, but leave it "pending" */ | ||
190 | return status; | ||
191 | } | ||
192 | /* Trigger mount for path component or follow link */ | ||
193 | } else if (ino->flags & AUTOFS_INF_PENDING || | ||
194 | autofs4_need_mount(flags)) { | ||
195 | DPRINTK("waiting for mount name=%.*s", | ||
196 | dentry->d_name.len, dentry->d_name.name); | ||
197 | |||
198 | spin_lock(&sbi->fs_lock); | ||
199 | ino->flags |= AUTOFS_INF_PENDING; | ||
200 | spin_unlock(&sbi->fs_lock); | ||
201 | status = autofs4_wait(sbi, dentry, NFY_MOUNT); | ||
202 | |||
203 | DPRINTK("mount done status=%d", status); | ||
204 | |||
205 | if (status) { | ||
206 | spin_lock(&sbi->fs_lock); | ||
207 | ino->flags &= ~AUTOFS_INF_PENDING; | ||
208 | spin_unlock(&sbi->fs_lock); | ||
209 | return status; | ||
210 | } | ||
211 | } | ||
212 | |||
213 | /* Initialize expiry counter after successful mount */ | ||
214 | ino->last_used = jiffies; | ||
215 | |||
216 | spin_lock(&sbi->fs_lock); | ||
217 | ino->flags &= ~AUTOFS_INF_PENDING; | ||
218 | spin_unlock(&sbi->fs_lock); | ||
219 | |||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | /* For autofs direct mounts the follow link triggers the mount */ | ||
224 | static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) | ||
225 | { | ||
226 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); | ||
227 | struct autofs_info *ino = autofs4_dentry_ino(dentry); | ||
228 | int oz_mode = autofs4_oz_mode(sbi); | ||
229 | unsigned int lookup_type; | ||
230 | int status; | ||
231 | |||
232 | DPRINTK("dentry=%p %.*s oz_mode=%d nd->flags=%d", | ||
233 | dentry, dentry->d_name.len, dentry->d_name.name, oz_mode, | ||
234 | nd->flags); | ||
235 | /* | ||
236 | * For an expire of a covered direct or offset mount we need | ||
237 | * to break out of follow_down() at the autofs mount trigger | ||
238 | * (d_mounted--), so we can see the expiring flag, and manage | ||
239 | * the blocking and following here until the expire is completed. | ||
240 | */ | ||
241 | if (oz_mode) { | ||
242 | spin_lock(&sbi->fs_lock); | ||
243 | if (ino->flags & AUTOFS_INF_EXPIRING) { | ||
244 | spin_unlock(&sbi->fs_lock); | ||
245 | /* Follow down to our covering mount. */ | ||
246 | if (!follow_down(&nd->path)) | ||
247 | goto done; | ||
248 | goto follow; | ||
249 | } | ||
250 | spin_unlock(&sbi->fs_lock); | ||
251 | goto done; | ||
252 | } | ||
253 | |||
254 | /* If an expire request is pending everyone must wait. */ | ||
255 | autofs4_expire_wait(dentry); | ||
256 | |||
257 | /* We trigger a mount for almost all flags */ | ||
258 | lookup_type = autofs4_need_mount(nd->flags); | ||
259 | spin_lock(&sbi->fs_lock); | ||
260 | spin_lock(&autofs4_lock); | ||
261 | spin_lock(&dentry->d_lock); | ||
262 | if (!(lookup_type || ino->flags & AUTOFS_INF_PENDING)) { | ||
263 | spin_unlock(&dentry->d_lock); | ||
264 | spin_unlock(&autofs4_lock); | ||
265 | spin_unlock(&sbi->fs_lock); | ||
266 | goto follow; | ||
267 | } | ||
268 | |||
269 | /* | ||
270 | * If the dentry contains directories then it is an autofs | ||
271 | * multi-mount with no root mount offset. So don't try to | ||
272 | * mount it again. | ||
273 | */ | ||
274 | if (ino->flags & AUTOFS_INF_PENDING || | ||
275 | (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs))) { | ||
276 | spin_unlock(&dentry->d_lock); | ||
277 | spin_unlock(&autofs4_lock); | ||
278 | spin_unlock(&sbi->fs_lock); | ||
279 | |||
280 | status = try_to_fill_dentry(dentry, nd->flags); | ||
281 | if (status) | ||
282 | goto out_error; | ||
283 | |||
284 | goto follow; | ||
285 | } | ||
286 | spin_unlock(&dentry->d_lock); | ||
287 | spin_unlock(&autofs4_lock); | ||
288 | spin_unlock(&sbi->fs_lock); | ||
289 | follow: | ||
290 | /* | ||
291 | * If there is no root mount it must be an autofs | ||
292 | * multi-mount with no root offset so we don't need | ||
293 | * to follow it. | ||
294 | */ | ||
295 | if (d_mountpoint(dentry)) { | ||
296 | if (!autofs4_follow_mount(&nd->path)) { | ||
297 | status = -ENOENT; | ||
298 | goto out_error; | ||
299 | } | ||
300 | } | ||
301 | |||
302 | done: | ||
303 | return NULL; | ||
304 | |||
305 | out_error: | ||
306 | path_put(&nd->path); | ||
307 | return ERR_PTR(status); | ||
308 | } | ||
309 | |||
310 | /* | ||
311 | * Revalidate is called on every cache lookup. Some of those | ||
312 | * cache lookups may actually happen while the dentry is not | ||
313 | * yet completely filled in, and revalidate has to delay such | ||
314 | * lookups.. | ||
315 | */ | ||
316 | static int autofs4_revalidate(struct dentry *dentry, struct nameidata *nd) | ||
317 | { | 143 | { |
318 | struct inode *dir; | 144 | struct autofs_info *ino = autofs4_dentry_ino(de); |
319 | struct autofs_sb_info *sbi; | 145 | struct autofs_sb_info *sbi = autofs4_sbi(de->d_sb); |
320 | int oz_mode; | ||
321 | int flags = nd ? nd->flags : 0; | ||
322 | int status = 1; | ||
323 | |||
324 | if (flags & LOOKUP_RCU) | ||
325 | return -ECHILD; | ||
326 | |||
327 | dir = dentry->d_parent->d_inode; | ||
328 | sbi = autofs4_sbi(dir->i_sb); | ||
329 | oz_mode = autofs4_oz_mode(sbi); | ||
330 | |||
331 | /* Pending dentry */ | ||
332 | spin_lock(&sbi->fs_lock); | ||
333 | if (autofs4_ispending(dentry)) { | ||
334 | /* The daemon never causes a mount to trigger */ | ||
335 | spin_unlock(&sbi->fs_lock); | ||
336 | |||
337 | if (oz_mode) | ||
338 | return 1; | ||
339 | |||
340 | /* | ||
341 | * If the directory has gone away due to an expire | ||
342 | * we have been called as ->d_revalidate() and so | ||
343 | * we need to return false and proceed to ->lookup(). | ||
344 | */ | ||
345 | if (autofs4_expire_wait(dentry) == -EAGAIN) | ||
346 | return 0; | ||
347 | |||
348 | /* | ||
349 | * A zero status is success otherwise we have a | ||
350 | * negative error code. | ||
351 | */ | ||
352 | status = try_to_fill_dentry(dentry, flags); | ||
353 | if (status == 0) | ||
354 | return 1; | ||
355 | |||
356 | return status; | ||
357 | } | ||
358 | spin_unlock(&sbi->fs_lock); | ||
359 | |||
360 | /* Negative dentry.. invalidate if "old" */ | ||
361 | if (dentry->d_inode == NULL) | ||
362 | return 0; | ||
363 | |||
364 | /* Check for a non-mountpoint directory with no contents */ | ||
365 | spin_lock(&autofs4_lock); | ||
366 | spin_lock(&dentry->d_lock); | ||
367 | if (S_ISDIR(dentry->d_inode->i_mode) && | ||
368 | !d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) { | ||
369 | DPRINTK("dentry=%p %.*s, emptydir", | ||
370 | dentry, dentry->d_name.len, dentry->d_name.name); | ||
371 | spin_unlock(&dentry->d_lock); | ||
372 | spin_unlock(&autofs4_lock); | ||
373 | |||
374 | /* The daemon never causes a mount to trigger */ | ||
375 | if (oz_mode) | ||
376 | return 1; | ||
377 | |||
378 | /* | ||
379 | * A zero status is success otherwise we have a | ||
380 | * negative error code. | ||
381 | */ | ||
382 | status = try_to_fill_dentry(dentry, flags); | ||
383 | if (status == 0) | ||
384 | return 1; | ||
385 | |||
386 | return status; | ||
387 | } | ||
388 | spin_unlock(&dentry->d_lock); | ||
389 | spin_unlock(&autofs4_lock); | ||
390 | |||
391 | return 1; | ||
392 | } | ||
393 | |||
394 | void autofs4_dentry_release(struct dentry *de) | ||
395 | { | ||
396 | struct autofs_info *inf; | ||
397 | 146 | ||
398 | DPRINTK("releasing %p", de); | 147 | DPRINTK("releasing %p", de); |
399 | 148 | ||
400 | inf = autofs4_dentry_ino(de); | 149 | if (!ino) |
401 | de->d_fsdata = NULL; | 150 | return; |
402 | |||
403 | if (inf) { | ||
404 | struct autofs_sb_info *sbi = autofs4_sbi(de->d_sb); | ||
405 | |||
406 | if (sbi) { | ||
407 | spin_lock(&sbi->lookup_lock); | ||
408 | if (!list_empty(&inf->active)) | ||
409 | list_del(&inf->active); | ||
410 | if (!list_empty(&inf->expiring)) | ||
411 | list_del(&inf->expiring); | ||
412 | spin_unlock(&sbi->lookup_lock); | ||
413 | } | ||
414 | |||
415 | inf->dentry = NULL; | ||
416 | inf->inode = NULL; | ||
417 | 151 | ||
418 | autofs4_free_ino(inf); | 152 | if (sbi) { |
153 | spin_lock(&sbi->lookup_lock); | ||
154 | if (!list_empty(&ino->active)) | ||
155 | list_del(&ino->active); | ||
156 | if (!list_empty(&ino->expiring)) | ||
157 | list_del(&ino->expiring); | ||
158 | spin_unlock(&sbi->lookup_lock); | ||
419 | } | 159 | } |
420 | } | ||
421 | 160 | ||
422 | /* For dentries of directories in the root dir */ | 161 | autofs4_free_ino(ino); |
423 | static const struct dentry_operations autofs4_root_dentry_operations = { | 162 | } |
424 | .d_revalidate = autofs4_revalidate, | ||
425 | .d_release = autofs4_dentry_release, | ||
426 | }; | ||
427 | |||
428 | /* For other dentries */ | ||
429 | static const struct dentry_operations autofs4_dentry_operations = { | ||
430 | .d_revalidate = autofs4_revalidate, | ||
431 | .d_release = autofs4_dentry_release, | ||
432 | }; | ||
433 | 163 | ||
434 | static struct dentry *autofs4_lookup_active(struct dentry *dentry) | 164 | static struct dentry *autofs4_lookup_active(struct dentry *dentry) |
435 | { | 165 | { |
@@ -541,51 +271,246 @@ next: | |||
541 | return NULL; | 271 | return NULL; |
542 | } | 272 | } |
543 | 273 | ||
274 | static int autofs4_mount_wait(struct dentry *dentry) | ||
275 | { | ||
276 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); | ||
277 | struct autofs_info *ino = autofs4_dentry_ino(dentry); | ||
278 | int status; | ||
279 | |||
280 | if (ino->flags & AUTOFS_INF_PENDING) { | ||
281 | DPRINTK("waiting for mount name=%.*s", | ||
282 | dentry->d_name.len, dentry->d_name.name); | ||
283 | status = autofs4_wait(sbi, dentry, NFY_MOUNT); | ||
284 | DPRINTK("mount wait done status=%d", status); | ||
285 | ino->last_used = jiffies; | ||
286 | return status; | ||
287 | } | ||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | static int do_expire_wait(struct dentry *dentry) | ||
292 | { | ||
293 | struct dentry *expiring; | ||
294 | |||
295 | expiring = autofs4_lookup_expiring(dentry); | ||
296 | if (!expiring) | ||
297 | return autofs4_expire_wait(dentry); | ||
298 | else { | ||
299 | /* | ||
300 | * If we are racing with expire the request might not | ||
301 | * be quite complete, but the directory has been removed | ||
302 | * so it must have been successful, just wait for it. | ||
303 | */ | ||
304 | autofs4_expire_wait(expiring); | ||
305 | autofs4_del_expiring(expiring); | ||
306 | dput(expiring); | ||
307 | } | ||
308 | return 0; | ||
309 | } | ||
310 | |||
311 | static struct dentry *autofs4_mountpoint_changed(struct path *path) | ||
312 | { | ||
313 | struct dentry *dentry = path->dentry; | ||
314 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); | ||
315 | |||
316 | /* | ||
317 | * If this is an indirect mount the dentry could have gone away | ||
318 | * as a result of an expire and a new one created. | ||
319 | */ | ||
320 | if (autofs_type_indirect(sbi->type) && d_unhashed(dentry)) { | ||
321 | struct dentry *parent = dentry->d_parent; | ||
322 | struct dentry *new = d_lookup(parent, &dentry->d_name); | ||
323 | if (!new) | ||
324 | return NULL; | ||
325 | dput(path->dentry); | ||
326 | path->dentry = new; | ||
327 | } | ||
328 | return path->dentry; | ||
329 | } | ||
330 | |||
331 | static struct vfsmount *autofs4_d_automount(struct path *path) | ||
332 | { | ||
333 | struct dentry *dentry = path->dentry; | ||
334 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); | ||
335 | struct autofs_info *ino = autofs4_dentry_ino(dentry); | ||
336 | int status; | ||
337 | |||
338 | DPRINTK("dentry=%p %.*s", | ||
339 | dentry, dentry->d_name.len, dentry->d_name.name); | ||
340 | |||
341 | /* | ||
342 | * Someone may have manually umounted this or it was a submount | ||
343 | * that has gone away. | ||
344 | */ | ||
345 | spin_lock(&dentry->d_lock); | ||
346 | if (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) { | ||
347 | if (!(dentry->d_flags & DCACHE_MANAGE_TRANSIT) && | ||
348 | (dentry->d_flags & DCACHE_NEED_AUTOMOUNT)) | ||
349 | __managed_dentry_set_transit(path->dentry); | ||
350 | } | ||
351 | spin_unlock(&dentry->d_lock); | ||
352 | |||
353 | /* The daemon never triggers a mount. */ | ||
354 | if (autofs4_oz_mode(sbi)) | ||
355 | return NULL; | ||
356 | |||
357 | /* | ||
358 | * If an expire request is pending everyone must wait. | ||
359 | * If the expire fails we're still mounted so continue | ||
360 | * the follow and return. A return of -EAGAIN (which only | ||
361 | * happens with indirect mounts) means the expire completed | ||
362 | * and the directory was removed, so just go ahead and try | ||
363 | * the mount. | ||
364 | */ | ||
365 | status = do_expire_wait(dentry); | ||
366 | if (status && status != -EAGAIN) | ||
367 | return NULL; | ||
368 | |||
369 | /* Callback to the daemon to perform the mount or wait */ | ||
370 | spin_lock(&sbi->fs_lock); | ||
371 | if (ino->flags & AUTOFS_INF_PENDING) { | ||
372 | spin_unlock(&sbi->fs_lock); | ||
373 | status = autofs4_mount_wait(dentry); | ||
374 | if (status) | ||
375 | return ERR_PTR(status); | ||
376 | spin_lock(&sbi->fs_lock); | ||
377 | goto done; | ||
378 | } | ||
379 | |||
380 | /* | ||
381 | * If the dentry is a symlink it's equivalent to a directory | ||
382 | * having d_mountpoint() true, so there's no need to call back | ||
383 | * to the daemon. | ||
384 | */ | ||
385 | if (dentry->d_inode && S_ISLNK(dentry->d_inode->i_mode)) | ||
386 | goto done; | ||
387 | if (!d_mountpoint(dentry)) { | ||
388 | /* | ||
389 | * It's possible that user space hasn't removed directories | ||
390 | * after umounting a rootless multi-mount, although it | ||
391 | * should. For v5 have_submounts() is sufficient to handle | ||
392 | * this because the leaves of the directory tree under the | ||
393 | * mount never trigger mounts themselves (they have an autofs | ||
394 | * trigger mount mounted on them). But v4 pseudo direct mounts | ||
395 | * do need the leaves to to trigger mounts. In this case we | ||
396 | * have no choice but to use the list_empty() check and | ||
397 | * require user space behave. | ||
398 | */ | ||
399 | if (sbi->version > 4) { | ||
400 | if (have_submounts(dentry)) | ||
401 | goto done; | ||
402 | } else { | ||
403 | spin_lock(&dentry->d_lock); | ||
404 | if (!list_empty(&dentry->d_subdirs)) { | ||
405 | spin_unlock(&dentry->d_lock); | ||
406 | goto done; | ||
407 | } | ||
408 | spin_unlock(&dentry->d_lock); | ||
409 | } | ||
410 | ino->flags |= AUTOFS_INF_PENDING; | ||
411 | spin_unlock(&sbi->fs_lock); | ||
412 | status = autofs4_mount_wait(dentry); | ||
413 | if (status) | ||
414 | return ERR_PTR(status); | ||
415 | spin_lock(&sbi->fs_lock); | ||
416 | ino->flags &= ~AUTOFS_INF_PENDING; | ||
417 | } | ||
418 | done: | ||
419 | if (!(ino->flags & AUTOFS_INF_EXPIRING)) { | ||
420 | /* | ||
421 | * Any needed mounting has been completed and the path updated | ||
422 | * so turn this into a normal dentry so we don't continually | ||
423 | * call ->d_automount() and ->d_manage(). | ||
424 | */ | ||
425 | spin_lock(&dentry->d_lock); | ||
426 | __managed_dentry_clear_transit(dentry); | ||
427 | /* | ||
428 | * Only clear DMANAGED_AUTOMOUNT for rootless multi-mounts and | ||
429 | * symlinks as in all other cases the dentry will be covered by | ||
430 | * an actual mount so ->d_automount() won't be called during | ||
431 | * the follow. | ||
432 | */ | ||
433 | if ((!d_mountpoint(dentry) && | ||
434 | !list_empty(&dentry->d_subdirs)) || | ||
435 | (dentry->d_inode && S_ISLNK(dentry->d_inode->i_mode))) | ||
436 | __managed_dentry_clear_automount(dentry); | ||
437 | spin_unlock(&dentry->d_lock); | ||
438 | } | ||
439 | spin_unlock(&sbi->fs_lock); | ||
440 | |||
441 | /* Mount succeeded, check if we ended up with a new dentry */ | ||
442 | dentry = autofs4_mountpoint_changed(path); | ||
443 | if (!dentry) | ||
444 | return ERR_PTR(-ENOENT); | ||
445 | |||
446 | return NULL; | ||
447 | } | ||
448 | |||
449 | int autofs4_d_manage(struct dentry *dentry, bool mounting_here, bool rcu_walk) | ||
450 | { | ||
451 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); | ||
452 | |||
453 | DPRINTK("dentry=%p %.*s", | ||
454 | dentry, dentry->d_name.len, dentry->d_name.name); | ||
455 | |||
456 | /* The daemon never waits. */ | ||
457 | if (autofs4_oz_mode(sbi) || mounting_here) { | ||
458 | if (!d_mountpoint(dentry)) | ||
459 | return -EISDIR; | ||
460 | return 0; | ||
461 | } | ||
462 | |||
463 | /* We need to sleep, so we need pathwalk to be in ref-mode */ | ||
464 | if (rcu_walk) | ||
465 | return -ECHILD; | ||
466 | |||
467 | /* Wait for pending expires */ | ||
468 | do_expire_wait(dentry); | ||
469 | |||
470 | /* | ||
471 | * This dentry may be under construction so wait on mount | ||
472 | * completion. | ||
473 | */ | ||
474 | return autofs4_mount_wait(dentry); | ||
475 | } | ||
476 | |||
544 | /* Lookups in the root directory */ | 477 | /* Lookups in the root directory */ |
545 | static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | 478 | static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) |
546 | { | 479 | { |
547 | struct autofs_sb_info *sbi; | 480 | struct autofs_sb_info *sbi; |
548 | struct autofs_info *ino; | 481 | struct autofs_info *ino; |
549 | struct dentry *expiring, *active; | 482 | struct dentry *active; |
550 | int oz_mode; | ||
551 | 483 | ||
552 | DPRINTK("name = %.*s", | 484 | DPRINTK("name = %.*s", dentry->d_name.len, dentry->d_name.name); |
553 | dentry->d_name.len, dentry->d_name.name); | ||
554 | 485 | ||
555 | /* File name too long to exist */ | 486 | /* File name too long to exist */ |
556 | if (dentry->d_name.len > NAME_MAX) | 487 | if (dentry->d_name.len > NAME_MAX) |
557 | return ERR_PTR(-ENAMETOOLONG); | 488 | return ERR_PTR(-ENAMETOOLONG); |
558 | 489 | ||
559 | sbi = autofs4_sbi(dir->i_sb); | 490 | sbi = autofs4_sbi(dir->i_sb); |
560 | oz_mode = autofs4_oz_mode(sbi); | ||
561 | 491 | ||
562 | DPRINTK("pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d", | 492 | DPRINTK("pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d", |
563 | current->pid, task_pgrp_nr(current), sbi->catatonic, oz_mode); | 493 | current->pid, task_pgrp_nr(current), sbi->catatonic, |
494 | autofs4_oz_mode(sbi)); | ||
564 | 495 | ||
565 | active = autofs4_lookup_active(dentry); | 496 | active = autofs4_lookup_active(dentry); |
566 | if (active) { | 497 | if (active) { |
567 | dentry = active; | 498 | return active; |
568 | ino = autofs4_dentry_ino(dentry); | ||
569 | } else { | 499 | } else { |
570 | /* | 500 | /* |
571 | * Mark the dentry incomplete but don't hash it. We do this | 501 | * A dentry that is not within the root can never trigger a |
572 | * to serialize our inode creation operations (symlink and | 502 | * mount operation, unless the directory already exists, so we |
573 | * mkdir) which prevents deadlock during the callback to | 503 | * can return fail immediately. The daemon however does need |
574 | * the daemon. Subsequent user space lookups for the same | 504 | * to create directories within the file system. |
575 | * dentry are placed on the wait queue while the daemon | ||
576 | * itself is allowed passage unresticted so the create | ||
577 | * operation itself can then hash the dentry. Finally, | ||
578 | * we check for the hashed dentry and return the newly | ||
579 | * hashed dentry. | ||
580 | */ | 505 | */ |
581 | d_set_d_op(dentry, &autofs4_root_dentry_operations); | 506 | if (!autofs4_oz_mode(sbi) && !IS_ROOT(dentry->d_parent)) |
507 | return ERR_PTR(-ENOENT); | ||
582 | 508 | ||
583 | /* | 509 | /* Mark entries in the root as mount triggers */ |
584 | * And we need to ensure that the same dentry is used for | 510 | if (autofs_type_indirect(sbi->type) && IS_ROOT(dentry->d_parent)) |
585 | * all following lookup calls until it is hashed so that | 511 | __managed_dentry_set_managed(dentry); |
586 | * the dentry flags are persistent throughout the request. | 512 | |
587 | */ | 513 | ino = autofs4_new_ino(sbi); |
588 | ino = autofs4_init_ino(NULL, sbi, 0555); | ||
589 | if (!ino) | 514 | if (!ino) |
590 | return ERR_PTR(-ENOMEM); | 515 | return ERR_PTR(-ENOMEM); |
591 | 516 | ||
@@ -596,82 +521,6 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s | |||
596 | 521 | ||
597 | d_instantiate(dentry, NULL); | 522 | d_instantiate(dentry, NULL); |
598 | } | 523 | } |
599 | |||
600 | if (!oz_mode) { | ||
601 | mutex_unlock(&dir->i_mutex); | ||
602 | expiring = autofs4_lookup_expiring(dentry); | ||
603 | if (expiring) { | ||
604 | /* | ||
605 | * If we are racing with expire the request might not | ||
606 | * be quite complete but the directory has been removed | ||
607 | * so it must have been successful, so just wait for it. | ||
608 | */ | ||
609 | autofs4_expire_wait(expiring); | ||
610 | autofs4_del_expiring(expiring); | ||
611 | dput(expiring); | ||
612 | } | ||
613 | |||
614 | spin_lock(&sbi->fs_lock); | ||
615 | ino->flags |= AUTOFS_INF_PENDING; | ||
616 | spin_unlock(&sbi->fs_lock); | ||
617 | if (dentry->d_op && dentry->d_op->d_revalidate) | ||
618 | (dentry->d_op->d_revalidate)(dentry, nd); | ||
619 | mutex_lock(&dir->i_mutex); | ||
620 | } | ||
621 | |||
622 | /* | ||
623 | * If we are still pending, check if we had to handle | ||
624 | * a signal. If so we can force a restart.. | ||
625 | */ | ||
626 | if (ino->flags & AUTOFS_INF_PENDING) { | ||
627 | /* See if we were interrupted */ | ||
628 | if (signal_pending(current)) { | ||
629 | sigset_t *sigset = ¤t->pending.signal; | ||
630 | if (sigismember (sigset, SIGKILL) || | ||
631 | sigismember (sigset, SIGQUIT) || | ||
632 | sigismember (sigset, SIGINT)) { | ||
633 | if (active) | ||
634 | dput(active); | ||
635 | return ERR_PTR(-ERESTARTNOINTR); | ||
636 | } | ||
637 | } | ||
638 | if (!oz_mode) { | ||
639 | spin_lock(&sbi->fs_lock); | ||
640 | ino->flags &= ~AUTOFS_INF_PENDING; | ||
641 | spin_unlock(&sbi->fs_lock); | ||
642 | } | ||
643 | } | ||
644 | |||
645 | /* | ||
646 | * If this dentry is unhashed, then we shouldn't honour this | ||
647 | * lookup. Returning ENOENT here doesn't do the right thing | ||
648 | * for all system calls, but it should be OK for the operations | ||
649 | * we permit from an autofs. | ||
650 | */ | ||
651 | if (!oz_mode && d_unhashed(dentry)) { | ||
652 | /* | ||
653 | * A user space application can (and has done in the past) | ||
654 | * remove and re-create this directory during the callback. | ||
655 | * This can leave us with an unhashed dentry, but a | ||
656 | * successful mount! So we need to perform another | ||
657 | * cached lookup in case the dentry now exists. | ||
658 | */ | ||
659 | struct dentry *parent = dentry->d_parent; | ||
660 | struct dentry *new = d_lookup(parent, &dentry->d_name); | ||
661 | if (new != NULL) | ||
662 | dentry = new; | ||
663 | else | ||
664 | dentry = ERR_PTR(-ENOENT); | ||
665 | |||
666 | if (active) | ||
667 | dput(active); | ||
668 | |||
669 | return dentry; | ||
670 | } | ||
671 | |||
672 | if (active) | ||
673 | return active; | ||
674 | |||
675 | return NULL; | 524 | return NULL; |
676 | } | 525 | } |
677 | 526 | ||
@@ -683,6 +532,7 @@ static int autofs4_dir_symlink(struct inode *dir, | |||
683 | struct autofs_info *ino = autofs4_dentry_ino(dentry); | 532 | struct autofs_info *ino = autofs4_dentry_ino(dentry); |
684 | struct autofs_info *p_ino; | 533 | struct autofs_info *p_ino; |
685 | struct inode *inode; | 534 | struct inode *inode; |
535 | size_t size = strlen(symname); | ||
686 | char *cp; | 536 | char *cp; |
687 | 537 | ||
688 | DPRINTK("%s <- %.*s", symname, | 538 | DPRINTK("%s <- %.*s", symname, |
@@ -691,45 +541,35 @@ static int autofs4_dir_symlink(struct inode *dir, | |||
691 | if (!autofs4_oz_mode(sbi)) | 541 | if (!autofs4_oz_mode(sbi)) |
692 | return -EACCES; | 542 | return -EACCES; |
693 | 543 | ||
694 | ino = autofs4_init_ino(ino, sbi, S_IFLNK | 0555); | 544 | BUG_ON(!ino); |
695 | if (!ino) | 545 | |
696 | return -ENOMEM; | 546 | autofs4_clean_ino(ino); |
697 | 547 | ||
698 | autofs4_del_active(dentry); | 548 | autofs4_del_active(dentry); |
699 | 549 | ||
700 | ino->size = strlen(symname); | 550 | cp = kmalloc(size + 1, GFP_KERNEL); |
701 | cp = kmalloc(ino->size + 1, GFP_KERNEL); | 551 | if (!cp) |
702 | if (!cp) { | ||
703 | if (!dentry->d_fsdata) | ||
704 | kfree(ino); | ||
705 | return -ENOMEM; | 552 | return -ENOMEM; |
706 | } | ||
707 | 553 | ||
708 | strcpy(cp, symname); | 554 | strcpy(cp, symname); |
709 | 555 | ||
710 | inode = autofs4_get_inode(dir->i_sb, ino); | 556 | inode = autofs4_get_inode(dir->i_sb, S_IFLNK | 0555); |
711 | if (!inode) { | 557 | if (!inode) { |
712 | kfree(cp); | 558 | kfree(cp); |
713 | if (!dentry->d_fsdata) | 559 | if (!dentry->d_fsdata) |
714 | kfree(ino); | 560 | kfree(ino); |
715 | return -ENOMEM; | 561 | return -ENOMEM; |
716 | } | 562 | } |
563 | inode->i_private = cp; | ||
564 | inode->i_size = size; | ||
717 | d_add(dentry, inode); | 565 | d_add(dentry, inode); |
718 | 566 | ||
719 | if (dir == dir->i_sb->s_root->d_inode) | 567 | dget(dentry); |
720 | d_set_d_op(dentry, &autofs4_root_dentry_operations); | ||
721 | else | ||
722 | d_set_d_op(dentry, &autofs4_dentry_operations); | ||
723 | |||
724 | dentry->d_fsdata = ino; | ||
725 | ino->dentry = dget(dentry); | ||
726 | atomic_inc(&ino->count); | 568 | atomic_inc(&ino->count); |
727 | p_ino = autofs4_dentry_ino(dentry->d_parent); | 569 | p_ino = autofs4_dentry_ino(dentry->d_parent); |
728 | if (p_ino && dentry->d_parent != dentry) | 570 | if (p_ino && dentry->d_parent != dentry) |
729 | atomic_inc(&p_ino->count); | 571 | atomic_inc(&p_ino->count); |
730 | ino->inode = inode; | ||
731 | 572 | ||
732 | ino->u.symlink = cp; | ||
733 | dir->i_mtime = CURRENT_TIME; | 573 | dir->i_mtime = CURRENT_TIME; |
734 | 574 | ||
735 | return 0; | 575 | return 0; |
@@ -782,6 +622,58 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry) | |||
782 | return 0; | 622 | return 0; |
783 | } | 623 | } |
784 | 624 | ||
625 | /* | ||
626 | * Version 4 of autofs provides a pseudo direct mount implementation | ||
627 | * that relies on directories at the leaves of a directory tree under | ||
628 | * an indirect mount to trigger mounts. To allow for this we need to | ||
629 | * set the DMANAGED_AUTOMOUNT and DMANAGED_TRANSIT flags on the leaves | ||
630 | * of the directory tree. There is no need to clear the automount flag | ||
631 | * following a mount or restore it after an expire because these mounts | ||
632 | * are always covered. However, it is neccessary to ensure that these | ||
633 | * flags are clear on non-empty directories to avoid unnecessary calls | ||
634 | * during path walks. | ||
635 | */ | ||
636 | static void autofs_set_leaf_automount_flags(struct dentry *dentry) | ||
637 | { | ||
638 | struct dentry *parent; | ||
639 | |||
640 | /* root and dentrys in the root are already handled */ | ||
641 | if (IS_ROOT(dentry->d_parent)) | ||
642 | return; | ||
643 | |||
644 | managed_dentry_set_managed(dentry); | ||
645 | |||
646 | parent = dentry->d_parent; | ||
647 | /* only consider parents below dentrys in the root */ | ||
648 | if (IS_ROOT(parent->d_parent)) | ||
649 | return; | ||
650 | managed_dentry_clear_managed(parent); | ||
651 | return; | ||
652 | } | ||
653 | |||
654 | static void autofs_clear_leaf_automount_flags(struct dentry *dentry) | ||
655 | { | ||
656 | struct list_head *d_child; | ||
657 | struct dentry *parent; | ||
658 | |||
659 | /* flags for dentrys in the root are handled elsewhere */ | ||
660 | if (IS_ROOT(dentry->d_parent)) | ||
661 | return; | ||
662 | |||
663 | managed_dentry_clear_managed(dentry); | ||
664 | |||
665 | parent = dentry->d_parent; | ||
666 | /* only consider parents below dentrys in the root */ | ||
667 | if (IS_ROOT(parent->d_parent)) | ||
668 | return; | ||
669 | d_child = &dentry->d_u.d_child; | ||
670 | /* Set parent managed if it's becoming empty */ | ||
671 | if (d_child->next == &parent->d_subdirs && | ||
672 | d_child->prev == &parent->d_subdirs) | ||
673 | managed_dentry_set_managed(parent); | ||
674 | return; | ||
675 | } | ||
676 | |||
785 | static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry) | 677 | static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry) |
786 | { | 678 | { |
787 | struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb); | 679 | struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb); |
@@ -809,6 +701,9 @@ static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry) | |||
809 | spin_unlock(&dentry->d_lock); | 701 | spin_unlock(&dentry->d_lock); |
810 | spin_unlock(&autofs4_lock); | 702 | spin_unlock(&autofs4_lock); |
811 | 703 | ||
704 | if (sbi->version < 5) | ||
705 | autofs_clear_leaf_automount_flags(dentry); | ||
706 | |||
812 | if (atomic_dec_and_test(&ino->count)) { | 707 | if (atomic_dec_and_test(&ino->count)) { |
813 | p_ino = autofs4_dentry_ino(dentry->d_parent); | 708 | p_ino = autofs4_dentry_ino(dentry->d_parent); |
814 | if (p_ino && dentry->d_parent != dentry) | 709 | if (p_ino && dentry->d_parent != dentry) |
@@ -837,32 +732,25 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
837 | DPRINTK("dentry %p, creating %.*s", | 732 | DPRINTK("dentry %p, creating %.*s", |
838 | dentry, dentry->d_name.len, dentry->d_name.name); | 733 | dentry, dentry->d_name.len, dentry->d_name.name); |
839 | 734 | ||
840 | ino = autofs4_init_ino(ino, sbi, S_IFDIR | 0555); | 735 | BUG_ON(!ino); |
841 | if (!ino) | 736 | |
842 | return -ENOMEM; | 737 | autofs4_clean_ino(ino); |
843 | 738 | ||
844 | autofs4_del_active(dentry); | 739 | autofs4_del_active(dentry); |
845 | 740 | ||
846 | inode = autofs4_get_inode(dir->i_sb, ino); | 741 | inode = autofs4_get_inode(dir->i_sb, S_IFDIR | 0555); |
847 | if (!inode) { | 742 | if (!inode) |
848 | if (!dentry->d_fsdata) | ||
849 | kfree(ino); | ||
850 | return -ENOMEM; | 743 | return -ENOMEM; |
851 | } | ||
852 | d_add(dentry, inode); | 744 | d_add(dentry, inode); |
853 | 745 | ||
854 | if (dir == dir->i_sb->s_root->d_inode) | 746 | if (sbi->version < 5) |
855 | d_set_d_op(dentry, &autofs4_root_dentry_operations); | 747 | autofs_set_leaf_automount_flags(dentry); |
856 | else | ||
857 | d_set_d_op(dentry, &autofs4_dentry_operations); | ||
858 | 748 | ||
859 | dentry->d_fsdata = ino; | 749 | dget(dentry); |
860 | ino->dentry = dget(dentry); | ||
861 | atomic_inc(&ino->count); | 750 | atomic_inc(&ino->count); |
862 | p_ino = autofs4_dentry_ino(dentry->d_parent); | 751 | p_ino = autofs4_dentry_ino(dentry->d_parent); |
863 | if (p_ino && dentry->d_parent != dentry) | 752 | if (p_ino && dentry->d_parent != dentry) |
864 | atomic_inc(&p_ino->count); | 753 | atomic_inc(&p_ino->count); |
865 | ino->inode = inode; | ||
866 | inc_nlink(dir); | 754 | inc_nlink(dir); |
867 | dir->i_mtime = CURRENT_TIME; | 755 | dir->i_mtime = CURRENT_TIME; |
868 | 756 | ||
@@ -944,8 +832,7 @@ static inline int autofs4_ask_umount(struct vfsmount *mnt, int __user *p) | |||
944 | int is_autofs4_dentry(struct dentry *dentry) | 832 | int is_autofs4_dentry(struct dentry *dentry) |
945 | { | 833 | { |
946 | return dentry && dentry->d_inode && | 834 | return dentry && dentry->d_inode && |
947 | (dentry->d_op == &autofs4_root_dentry_operations || | 835 | dentry->d_op == &autofs4_dentry_operations && |
948 | dentry->d_op == &autofs4_dentry_operations) && | ||
949 | dentry->d_fsdata != NULL; | 836 | dentry->d_fsdata != NULL; |
950 | } | 837 | } |
951 | 838 | ||