.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved |
---|
3 | 4 | * Copyright 1999-2000 Jeremy Fitzhardinge <jeremy@goop.org> |
---|
4 | 5 | * Copyright 2001-2006 Ian Kent <raven@themaw.net> |
---|
5 | | - * |
---|
6 | | - * This file is part of the Linux kernel and is made available under |
---|
7 | | - * the terms of the GNU General Public License, version 2, or at your |
---|
8 | | - * option, any later version, incorporated herein by reference. |
---|
9 | 6 | */ |
---|
10 | 7 | |
---|
11 | 8 | #include <linux/capability.h> |
---|
.. | .. |
---|
63 | 60 | .d_release = autofs_dentry_release, |
---|
64 | 61 | }; |
---|
65 | 62 | |
---|
66 | | -static void autofs_add_active(struct dentry *dentry) |
---|
67 | | -{ |
---|
68 | | - struct autofs_sb_info *sbi = autofs_sbi(dentry->d_sb); |
---|
69 | | - struct autofs_info *ino; |
---|
70 | | - |
---|
71 | | - ino = autofs_dentry_ino(dentry); |
---|
72 | | - if (ino) { |
---|
73 | | - spin_lock(&sbi->lookup_lock); |
---|
74 | | - if (!ino->active_count) { |
---|
75 | | - if (list_empty(&ino->active)) |
---|
76 | | - list_add(&ino->active, &sbi->active_list); |
---|
77 | | - } |
---|
78 | | - ino->active_count++; |
---|
79 | | - spin_unlock(&sbi->lookup_lock); |
---|
80 | | - } |
---|
81 | | -} |
---|
82 | | - |
---|
83 | 63 | static void autofs_del_active(struct dentry *dentry) |
---|
84 | 64 | { |
---|
85 | 65 | struct autofs_sb_info *sbi = autofs_sbi(dentry->d_sb); |
---|
86 | 66 | struct autofs_info *ino; |
---|
87 | 67 | |
---|
88 | 68 | ino = autofs_dentry_ino(dentry); |
---|
89 | | - if (ino) { |
---|
90 | | - spin_lock(&sbi->lookup_lock); |
---|
91 | | - ino->active_count--; |
---|
92 | | - if (!ino->active_count) { |
---|
93 | | - if (!list_empty(&ino->active)) |
---|
94 | | - list_del_init(&ino->active); |
---|
95 | | - } |
---|
96 | | - spin_unlock(&sbi->lookup_lock); |
---|
97 | | - } |
---|
| 69 | + spin_lock(&sbi->lookup_lock); |
---|
| 70 | + list_del_init(&ino->active); |
---|
| 71 | + spin_unlock(&sbi->lookup_lock); |
---|
98 | 72 | } |
---|
99 | 73 | |
---|
100 | 74 | static int autofs_dir_open(struct inode *inode, struct file *file) |
---|
.. | .. |
---|
275 | 249 | pr_debug("waiting for mount name=%pd\n", path->dentry); |
---|
276 | 250 | status = autofs_wait(sbi, path, NFY_MOUNT); |
---|
277 | 251 | pr_debug("mount wait done status=%d\n", status); |
---|
| 252 | + ino->last_used = jiffies; |
---|
| 253 | + return status; |
---|
278 | 254 | } |
---|
279 | | - ino->last_used = jiffies; |
---|
| 255 | + if (!(sbi->flags & AUTOFS_SBI_STRICTEXPIRE)) |
---|
| 256 | + ino->last_used = jiffies; |
---|
280 | 257 | return status; |
---|
281 | 258 | } |
---|
282 | 259 | |
---|
.. | .. |
---|
510 | 487 | sbi = autofs_sbi(dir->i_sb); |
---|
511 | 488 | |
---|
512 | 489 | pr_debug("pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d\n", |
---|
513 | | - current->pid, task_pgrp_nr(current), sbi->catatonic, |
---|
| 490 | + current->pid, task_pgrp_nr(current), |
---|
| 491 | + sbi->flags & AUTOFS_SBI_CATATONIC, |
---|
514 | 492 | autofs_oz_mode(sbi)); |
---|
515 | 493 | |
---|
516 | 494 | active = autofs_lookup_active(dentry); |
---|
.. | .. |
---|
526 | 504 | if (!autofs_oz_mode(sbi) && !IS_ROOT(dentry->d_parent)) |
---|
527 | 505 | return ERR_PTR(-ENOENT); |
---|
528 | 506 | |
---|
529 | | - /* Mark entries in the root as mount triggers */ |
---|
530 | | - if (IS_ROOT(dentry->d_parent) && |
---|
531 | | - autofs_type_indirect(sbi->type)) |
---|
532 | | - __managed_dentry_set_managed(dentry); |
---|
533 | | - |
---|
534 | 507 | ino = autofs_new_ino(sbi); |
---|
535 | 508 | if (!ino) |
---|
536 | 509 | return ERR_PTR(-ENOMEM); |
---|
537 | 510 | |
---|
| 511 | + spin_lock(&sbi->lookup_lock); |
---|
| 512 | + spin_lock(&dentry->d_lock); |
---|
| 513 | + /* Mark entries in the root as mount triggers */ |
---|
| 514 | + if (IS_ROOT(dentry->d_parent) && |
---|
| 515 | + autofs_type_indirect(sbi->type)) |
---|
| 516 | + __managed_dentry_set_managed(dentry); |
---|
538 | 517 | dentry->d_fsdata = ino; |
---|
539 | 518 | ino->dentry = dentry; |
---|
540 | 519 | |
---|
541 | | - autofs_add_active(dentry); |
---|
| 520 | + list_add(&ino->active, &sbi->active_list); |
---|
| 521 | + spin_unlock(&sbi->lookup_lock); |
---|
| 522 | + spin_unlock(&dentry->d_lock); |
---|
542 | 523 | } |
---|
543 | 524 | return NULL; |
---|
544 | 525 | } |
---|
.. | .. |
---|
563 | 544 | * autofs mount is catatonic but the state of an autofs |
---|
564 | 545 | * file system needs to be preserved over restarts. |
---|
565 | 546 | */ |
---|
566 | | - if (sbi->catatonic) |
---|
| 547 | + if (sbi->flags & AUTOFS_SBI_CATATONIC) |
---|
567 | 548 | return -EACCES; |
---|
568 | 549 | |
---|
569 | 550 | BUG_ON(!ino); |
---|
.. | .. |
---|
588 | 569 | d_add(dentry, inode); |
---|
589 | 570 | |
---|
590 | 571 | dget(dentry); |
---|
591 | | - atomic_inc(&ino->count); |
---|
| 572 | + ino->count++; |
---|
592 | 573 | p_ino = autofs_dentry_ino(dentry->d_parent); |
---|
593 | | - if (p_ino && !IS_ROOT(dentry)) |
---|
594 | | - atomic_inc(&p_ino->count); |
---|
| 574 | + p_ino->count++; |
---|
595 | 575 | |
---|
596 | 576 | dir->i_mtime = current_time(dir); |
---|
597 | 577 | |
---|
.. | .. |
---|
626 | 606 | * autofs mount is catatonic but the state of an autofs |
---|
627 | 607 | * file system needs to be preserved over restarts. |
---|
628 | 608 | */ |
---|
629 | | - if (sbi->catatonic) |
---|
| 609 | + if (sbi->flags & AUTOFS_SBI_CATATONIC) |
---|
630 | 610 | return -EACCES; |
---|
631 | 611 | |
---|
632 | | - if (atomic_dec_and_test(&ino->count)) { |
---|
633 | | - p_ino = autofs_dentry_ino(dentry->d_parent); |
---|
634 | | - if (p_ino && !IS_ROOT(dentry)) |
---|
635 | | - atomic_dec(&p_ino->count); |
---|
636 | | - } |
---|
| 612 | + ino->count--; |
---|
| 613 | + p_ino = autofs_dentry_ino(dentry->d_parent); |
---|
| 614 | + p_ino->count--; |
---|
637 | 615 | dput(ino->dentry); |
---|
638 | 616 | |
---|
639 | 617 | d_inode(dentry)->i_size = 0; |
---|
.. | .. |
---|
679 | 657 | |
---|
680 | 658 | static void autofs_clear_leaf_automount_flags(struct dentry *dentry) |
---|
681 | 659 | { |
---|
682 | | - struct list_head *d_child; |
---|
683 | 660 | struct dentry *parent; |
---|
684 | 661 | |
---|
685 | 662 | /* flags for dentrys in the root are handled elsewhere */ |
---|
.. | .. |
---|
692 | 669 | /* only consider parents below dentrys in the root */ |
---|
693 | 670 | if (IS_ROOT(parent->d_parent)) |
---|
694 | 671 | return; |
---|
695 | | - d_child = &dentry->d_child; |
---|
696 | | - /* Set parent managed if it's becoming empty */ |
---|
697 | | - if (d_child->next == &parent->d_subdirs && |
---|
698 | | - d_child->prev == &parent->d_subdirs) |
---|
| 672 | + if (autofs_dentry_ino(parent)->count == 2) |
---|
699 | 673 | managed_dentry_set_managed(parent); |
---|
700 | 674 | } |
---|
701 | 675 | |
---|
.. | .. |
---|
714 | 688 | * autofs mount is catatonic but the state of an autofs |
---|
715 | 689 | * file system needs to be preserved over restarts. |
---|
716 | 690 | */ |
---|
717 | | - if (sbi->catatonic) |
---|
| 691 | + if (sbi->flags & AUTOFS_SBI_CATATONIC) |
---|
718 | 692 | return -EACCES; |
---|
719 | 693 | |
---|
720 | | - spin_lock(&sbi->lookup_lock); |
---|
721 | | - if (!simple_empty(dentry)) { |
---|
722 | | - spin_unlock(&sbi->lookup_lock); |
---|
| 694 | + if (ino->count != 1) |
---|
723 | 695 | return -ENOTEMPTY; |
---|
724 | | - } |
---|
| 696 | + |
---|
| 697 | + spin_lock(&sbi->lookup_lock); |
---|
725 | 698 | __autofs_add_expiring(dentry); |
---|
726 | 699 | d_drop(dentry); |
---|
727 | 700 | spin_unlock(&sbi->lookup_lock); |
---|
.. | .. |
---|
729 | 702 | if (sbi->version < 5) |
---|
730 | 703 | autofs_clear_leaf_automount_flags(dentry); |
---|
731 | 704 | |
---|
732 | | - if (atomic_dec_and_test(&ino->count)) { |
---|
733 | | - p_ino = autofs_dentry_ino(dentry->d_parent); |
---|
734 | | - if (p_ino && dentry->d_parent != dentry) |
---|
735 | | - atomic_dec(&p_ino->count); |
---|
736 | | - } |
---|
| 705 | + ino->count--; |
---|
| 706 | + p_ino = autofs_dentry_ino(dentry->d_parent); |
---|
| 707 | + p_ino->count--; |
---|
737 | 708 | dput(ino->dentry); |
---|
738 | 709 | d_inode(dentry)->i_size = 0; |
---|
739 | 710 | clear_nlink(d_inode(dentry)); |
---|
.. | .. |
---|
759 | 730 | * autofs mount is catatonic but the state of an autofs |
---|
760 | 731 | * file system needs to be preserved over restarts. |
---|
761 | 732 | */ |
---|
762 | | - if (sbi->catatonic) |
---|
| 733 | + if (sbi->flags & AUTOFS_SBI_CATATONIC) |
---|
763 | 734 | return -EACCES; |
---|
764 | 735 | |
---|
765 | 736 | pr_debug("dentry %p, creating %pd\n", dentry, dentry); |
---|
.. | .. |
---|
779 | 750 | autofs_set_leaf_automount_flags(dentry); |
---|
780 | 751 | |
---|
781 | 752 | dget(dentry); |
---|
782 | | - atomic_inc(&ino->count); |
---|
| 753 | + ino->count++; |
---|
783 | 754 | p_ino = autofs_dentry_ino(dentry->d_parent); |
---|
784 | | - if (p_ino && !IS_ROOT(dentry)) |
---|
785 | | - atomic_inc(&p_ino->count); |
---|
| 755 | + p_ino->count++; |
---|
786 | 756 | inc_nlink(dir); |
---|
787 | 757 | dir->i_mtime = current_time(dir); |
---|
788 | 758 | |
---|