aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/filesystems
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2011-01-14 13:45:21 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2011-01-15 20:05:03 -0500
commit9875cf806403fae66b2410a3c2cc820d97731e04 (patch)
tree6f9546b400716766af95e0f78e3d600e765b2b51 /Documentation/filesystems
parent1a8edf40e7c3eee955e0dd0316a7c9d85e36f597 (diff)
Add a dentry op to handle automounting rather than abusing follow_link()
Add a dentry op (d_automount) to handle automounting directories rather than abusing the follow_link() inode operation. The operation is keyed off a new dentry flag (DCACHE_NEED_AUTOMOUNT). This also makes it easier to add an AT_ flag to suppress terminal segment automount during pathwalk and removes the need for the kludge code in the pathwalk algorithm to handle directories with follow_link() semantics. The ->d_automount() dentry operation: struct vfsmount *(*d_automount)(struct path *mountpoint); takes a pointer to the directory to be mounted upon, which is expected to provide sufficient data to determine what should be mounted. If successful, it should return the vfsmount struct it creates (which it should also have added to the namespace using do_add_mount() or similar). If there's a collision with another automount attempt, NULL should be returned. If the directory specified by the parameter should be used directly rather than being mounted upon, -EISDIR should be returned. In any other case, an error code should be returned. The ->d_automount() operation is called with no locks held and may sleep. At this point the pathwalk algorithm will be in ref-walk mode. Within fs/namei.c itself, a new pathwalk subroutine (follow_automount()) is added to handle mountpoints. It will return -EREMOTE if the automount flag was set, but no d_automount() op was supplied, -ELOOP if we've encountered too many symlinks or mountpoints, -EISDIR if the walk point should be used without mounting and 0 if successful. The path will be updated to point to the mounted filesystem if a successful automount took place. __follow_mount() is replaced by follow_managed() which is more generic (especially with the patch that adds ->d_manage()). This handles transits from directories during pathwalk, including automounting and skipping over mountpoints (and holding processes with the next patch). __follow_mount_rcu() will jump out of RCU-walk mode if it encounters an automount point with nothing mounted on it. follow_dotdot*() does not handle automounts as you don't want to trigger them whilst following "..". I've also extracted the mount/don't-mount logic from autofs4 and included it here. It makes the mount go ahead anyway if someone calls open() or creat(), tries to traverse the directory, tries to chdir/chroot/etc. into the directory, or sticks a '/' on the end of the pathname. If they do a stat(), however, they'll only trigger the automount if they didn't also say O_NOFOLLOW. I've also added an inode flag (S_AUTOMOUNT) so that filesystems can mark their inodes as automount points. This flag is automatically propagated to the dentry as DCACHE_NEED_AUTOMOUNT by __d_instantiate(). This saves NFS and could save AFS a private flag bit apiece, but is not strictly necessary. It would be preferable to do the propagation in d_set_d_op(), but that doesn't normally have access to the inode. [AV: fixed breakage in case if __follow_mount_rcu() fails and nameidata_drop_rcu() succeeds in RCU case of do_lookup(); we need to fall through to non-RCU case after that, rather than just returning with ungrabbed *path] Signed-off-by: David Howells <dhowells@redhat.com> Was-Acked-by: Ian Kent <raven@themaw.net> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'Documentation/filesystems')
-rw-r--r--Documentation/filesystems/Locking2
-rw-r--r--Documentation/filesystems/vfs.txt14
2 files changed, 16 insertions, 0 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index 977d8919cc69..5f0c52a07386 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -19,6 +19,7 @@ prototypes:
19 void (*d_release)(struct dentry *); 19 void (*d_release)(struct dentry *);
20 void (*d_iput)(struct dentry *, struct inode *); 20 void (*d_iput)(struct dentry *, struct inode *);
21 char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen); 21 char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen);
22 struct vfsmount *(*d_automount)(struct path *path);
22 23
23locking rules: 24locking rules:
24 rename_lock ->d_lock may block rcu-walk 25 rename_lock ->d_lock may block rcu-walk
@@ -29,6 +30,7 @@ d_delete: no yes no no
29d_release: no no yes no 30d_release: no no yes no
30d_iput: no no yes no 31d_iput: no no yes no
31d_dname: no no no no 32d_dname: no no no no
33d_automount: no no yes no
32 34
33--------------------------- inode_operations --------------------------- 35--------------------------- inode_operations ---------------------------
34prototypes: 36prototypes:
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index cae6d27c9f5b..726a4f6fa3c9 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -864,6 +864,7 @@ struct dentry_operations {
864 void (*d_release)(struct dentry *); 864 void (*d_release)(struct dentry *);
865 void (*d_iput)(struct dentry *, struct inode *); 865 void (*d_iput)(struct dentry *, struct inode *);
866 char *(*d_dname)(struct dentry *, char *, int); 866 char *(*d_dname)(struct dentry *, char *, int);
867 struct vfsmount *(*d_automount)(struct path *);
867}; 868};
868 869
869 d_revalidate: called when the VFS needs to revalidate a dentry. This 870 d_revalidate: called when the VFS needs to revalidate a dentry. This
@@ -930,6 +931,19 @@ struct dentry_operations {
930 at the end of the buffer, and returns a pointer to the first char. 931 at the end of the buffer, and returns a pointer to the first char.
931 dynamic_dname() helper function is provided to take care of this. 932 dynamic_dname() helper function is provided to take care of this.
932 933
934 d_automount: called when an automount dentry is to be traversed (optional).
935 This should create a new VFS mount record, mount it on the directory
936 and return the record to the caller. The caller is supplied with a
937 path parameter giving the automount directory to describe the automount
938 target and the parent VFS mount record to provide inheritable mount
939 parameters. NULL should be returned if someone else managed to make
940 the automount first. If the automount failed, then an error code
941 should be returned.
942
943 This function is only used if DCACHE_NEED_AUTOMOUNT is set on the
944 dentry. This is set by __d_instantiate() if S_AUTOMOUNT is set on the
945 inode being added.
946
933Example : 947Example :
934 948
935static char *pipefs_dname(struct dentry *dent, char *buffer, int buflen) 949static char *pipefs_dname(struct dentry *dent, char *buffer, int buflen)