Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

autofs4: Add v4 pseudo direct mount support

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.

This patch adds support for that functionality.

Signed-off-by: Ian Kent <raven@themaw.net>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

authored by

Ian Kent and committed by
Al Viro
dd89f90d 9e3fea16

+58
+58
fs/autofs4/root.c
··· 630 630 return 0; 631 631 } 632 632 633 + /* 634 + * Version 4 of autofs provides a pseudo direct mount implementation 635 + * that relies on directories at the leaves of a directory tree under 636 + * an indirect mount to trigger mounts. To allow for this we need to 637 + * set the DMANAGED_AUTOMOUNT and DMANAGED_TRANSIT flags on the leaves 638 + * of the directory tree. There is no need to clear the automount flag 639 + * following a mount or restore it after an expire because these mounts 640 + * are always covered. However, it is neccessary to ensure that these 641 + * flags are clear on non-empty directories to avoid unnecessary calls 642 + * during path walks. 643 + */ 644 + static void autofs_set_leaf_automount_flags(struct dentry *dentry) 645 + { 646 + struct dentry *parent; 647 + 648 + /* root and dentrys in the root are already handled */ 649 + if (IS_ROOT(dentry->d_parent)) 650 + return; 651 + 652 + managed_dentry_set_managed(dentry); 653 + 654 + parent = dentry->d_parent; 655 + /* only consider parents below dentrys in the root */ 656 + if (IS_ROOT(parent->d_parent)) 657 + return; 658 + managed_dentry_clear_managed(parent); 659 + return; 660 + } 661 + 662 + static void autofs_clear_leaf_automount_flags(struct dentry *dentry) 663 + { 664 + struct list_head *d_child; 665 + struct dentry *parent; 666 + 667 + /* flags for dentrys in the root are handled elsewhere */ 668 + if (IS_ROOT(dentry->d_parent)) 669 + return; 670 + 671 + managed_dentry_clear_managed(dentry); 672 + 673 + parent = dentry->d_parent; 674 + /* only consider parents below dentrys in the root */ 675 + if (IS_ROOT(parent->d_parent)) 676 + return; 677 + d_child = &dentry->d_u.d_child; 678 + /* Set parent managed if it's becoming empty */ 679 + if (d_child->next == &parent->d_subdirs && 680 + d_child->prev == &parent->d_subdirs) 681 + managed_dentry_set_managed(parent); 682 + return; 683 + } 684 + 633 685 static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry) 634 686 { 635 687 struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb); ··· 708 656 __d_drop(dentry); 709 657 spin_unlock(&dentry->d_lock); 710 658 spin_unlock(&autofs4_lock); 659 + 660 + if (sbi->version < 5) 661 + autofs_clear_leaf_automount_flags(dentry); 711 662 712 663 if (atomic_dec_and_test(&ino->count)) { 713 664 p_ino = autofs4_dentry_ino(dentry->d_parent); ··· 753 698 return -ENOMEM; 754 699 } 755 700 d_add(dentry, inode); 701 + 702 + if (sbi->version < 5) 703 + autofs_set_leaf_automount_flags(dentry); 756 704 757 705 dentry->d_fsdata = ino; 758 706 ino->dentry = dget(dentry);