aboutsummaryrefslogtreecommitdiffstats
path: root/fs/autofs4
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2014-10-13 18:52:16 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-13 20:18:16 -0400
commita5d1dba1430f059d5bb4bf1d95274ff01ccad3d9 (patch)
tree44a1ab49022175e85b81e9674059230124c62713 /fs/autofs4
parent23bfc2a24ea3d993cc5cc90c9970654e7232502e (diff)
autofs4: factor should_expire() out of autofs4_expire_indirect.
Future patch will potentially call this twice, so make it separate. Signed-off-by: NeilBrown <neilb@suse.de> Reviewed-by: Ian Kent <raven@themaw.net> Tested-by: Ian Kent <raven@themaw.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/autofs4')
-rw-r--r--fs/autofs4/expire.c162
1 files changed, 88 insertions, 74 deletions
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
index 1695eda8ac18..d03bedc7369f 100644
--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -339,6 +339,89 @@ out:
339 return NULL; 339 return NULL;
340} 340}
341 341
342/* Check if 'dentry' should expire, or return a nearby
343 * dentry that is suitable.
344 * If returned dentry is different from arg dentry,
345 * then a dget() reference was taken, else not.
346 */
347static struct dentry *should_expire(struct dentry *dentry,
348 struct vfsmount *mnt,
349 unsigned long timeout,
350 int how)
351{
352 int do_now = how & AUTOFS_EXP_IMMEDIATE;
353 int exp_leaves = how & AUTOFS_EXP_LEAVES;
354 struct autofs_info *ino = autofs4_dentry_ino(dentry);
355 unsigned int ino_count;
356
357 /* No point expiring a pending mount */
358 if (ino->flags & AUTOFS_INF_PENDING)
359 return NULL;
360
361 /*
362 * Case 1: (i) indirect mount or top level pseudo direct mount
363 * (autofs-4.1).
364 * (ii) indirect mount with offset mount, check the "/"
365 * offset (autofs-5.0+).
366 */
367 if (d_mountpoint(dentry)) {
368 DPRINTK("checking mountpoint %p %.*s",
369 dentry, (int)dentry->d_name.len, dentry->d_name.name);
370
371 /* Can we umount this guy */
372 if (autofs4_mount_busy(mnt, dentry))
373 return NULL;
374
375 /* Can we expire this guy */
376 if (autofs4_can_expire(dentry, timeout, do_now))
377 return dentry;
378 return NULL;
379 }
380
381 if (dentry->d_inode && S_ISLNK(dentry->d_inode->i_mode)) {
382 DPRINTK("checking symlink %p %.*s",
383 dentry, (int)dentry->d_name.len, dentry->d_name.name);
384 /*
385 * A symlink can't be "busy" in the usual sense so
386 * just check last used for expire timeout.
387 */
388 if (autofs4_can_expire(dentry, timeout, do_now))
389 return dentry;
390 return NULL;
391 }
392
393 if (simple_empty(dentry))
394 return NULL;
395
396 /* Case 2: tree mount, expire iff entire tree is not busy */
397 if (!exp_leaves) {
398 /* Path walk currently on this dentry? */
399 ino_count = atomic_read(&ino->count) + 1;
400 if (d_count(dentry) > ino_count)
401 return NULL;
402
403 if (!autofs4_tree_busy(mnt, dentry, timeout, do_now))
404 return dentry;
405 /*
406 * Case 3: pseudo direct mount, expire individual leaves
407 * (autofs-4.1).
408 */
409 } else {
410 /* Path walk currently on this dentry? */
411 struct dentry *expired;
412 ino_count = atomic_read(&ino->count) + 1;
413 if (d_count(dentry) > ino_count)
414 return NULL;
415
416 expired = autofs4_check_leaves(mnt, dentry, timeout, do_now);
417 if (expired) {
418 if (expired == dentry)
419 dput(dentry);
420 return expired;
421 }
422 }
423 return NULL;
424}
342/* 425/*
343 * Find an eligible tree to time-out 426 * Find an eligible tree to time-out
344 * A tree is eligible if :- 427 * A tree is eligible if :-
@@ -353,11 +436,8 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
353 unsigned long timeout; 436 unsigned long timeout;
354 struct dentry *root = sb->s_root; 437 struct dentry *root = sb->s_root;
355 struct dentry *dentry; 438 struct dentry *dentry;
356 struct dentry *expired = NULL; 439 struct dentry *expired;
357 int do_now = how & AUTOFS_EXP_IMMEDIATE;
358 int exp_leaves = how & AUTOFS_EXP_LEAVES;
359 struct autofs_info *ino; 440 struct autofs_info *ino;
360 unsigned int ino_count;
361 441
362 if (!root) 442 if (!root)
363 return NULL; 443 return NULL;
@@ -368,78 +448,12 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
368 dentry = NULL; 448 dentry = NULL;
369 while ((dentry = get_next_positive_subdir(dentry, root))) { 449 while ((dentry = get_next_positive_subdir(dentry, root))) {
370 spin_lock(&sbi->fs_lock); 450 spin_lock(&sbi->fs_lock);
371 ino = autofs4_dentry_ino(dentry); 451 expired = should_expire(dentry, mnt, timeout, how);
372 /* No point expiring a pending mount */ 452 if (expired) {
373 if (ino->flags & AUTOFS_INF_PENDING) 453 if (expired != dentry)
374 goto next;
375
376 /*
377 * Case 1: (i) indirect mount or top level pseudo direct mount
378 * (autofs-4.1).
379 * (ii) indirect mount with offset mount, check the "/"
380 * offset (autofs-5.0+).
381 */
382 if (d_mountpoint(dentry)) {
383 DPRINTK("checking mountpoint %p %.*s",
384 dentry, (int)dentry->d_name.len, dentry->d_name.name);
385
386 /* Can we umount this guy */
387 if (autofs4_mount_busy(mnt, dentry))
388 goto next;
389
390 /* Can we expire this guy */
391 if (autofs4_can_expire(dentry, timeout, do_now)) {
392 expired = dentry;
393 goto found;
394 }
395 goto next;
396 }
397
398 if (dentry->d_inode && S_ISLNK(dentry->d_inode->i_mode)) {
399 DPRINTK("checking symlink %p %.*s",
400 dentry, (int)dentry->d_name.len, dentry->d_name.name);
401 /*
402 * A symlink can't be "busy" in the usual sense so
403 * just check last used for expire timeout.
404 */
405 if (autofs4_can_expire(dentry, timeout, do_now)) {
406 expired = dentry;
407 goto found;
408 }
409 goto next;
410 }
411
412 if (simple_empty(dentry))
413 goto next;
414
415 /* Case 2: tree mount, expire iff entire tree is not busy */
416 if (!exp_leaves) {
417 /* Path walk currently on this dentry? */
418 ino_count = atomic_read(&ino->count) + 1;
419 if (d_count(dentry) > ino_count)
420 goto next;
421
422 if (!autofs4_tree_busy(mnt, dentry, timeout, do_now)) {
423 expired = dentry;
424 goto found;
425 }
426 /*
427 * Case 3: pseudo direct mount, expire individual leaves
428 * (autofs-4.1).
429 */
430 } else {
431 /* Path walk currently on this dentry? */
432 ino_count = atomic_read(&ino->count) + 1;
433 if (d_count(dentry) > ino_count)
434 goto next;
435
436 expired = autofs4_check_leaves(mnt, dentry, timeout, do_now);
437 if (expired) {
438 dput(dentry); 454 dput(dentry);
439 goto found; 455 goto found;
440 }
441 } 456 }
442next:
443 spin_unlock(&sbi->fs_lock); 457 spin_unlock(&sbi->fs_lock);
444 } 458 }
445 return NULL; 459 return NULL;