Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 052b398a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull vfs updates from Al Viro:
 "In this pile: pathname resolution rewrite.

   - recursion in link_path_walk() is gone.

   - nesting limits on symlinks are gone (the only limit remaining is
     that the total amount of symlinks is no more than 40, no matter how
     nested).

   - "fast" (inline) symlinks are handled without leaving rcuwalk mode.

   - stack footprint (independent of the nesting) is below kilobyte now,
     about on par with what it used to be with one level of nested
     symlinks and ~2.8 times lower than it used to be in the worst case.

   - struct nameidata is entirely private to fs/namei.c now (not even
     opaque pointers are being passed around).

   - ->follow_link() and ->put_link() calling conventions had been
     changed; all in-tree filesystems converted, out-of-tree should be
     able to follow reasonably easily.

     For out-of-tree conversions, see Documentation/filesystems/porting
     for details (and in-tree filesystems for examples of conversion).

  That has sat in -next since mid-May, seems to survive all testing
  without regressions and merges clean with v4.1"

* 'for-linus-1' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (131 commits)
  turn user_{path_at,path,lpath,path_dir}() into static inlines
  namei: move saved_nd pointer into struct nameidata
  inline user_path_create()
  inline user_path_parent()
  namei: trim do_last() arguments
  namei: stash dfd and name into nameidata
  namei: fold path_cleanup() into terminate_walk()
  namei: saner calling conventions for filename_parentat()
  namei: saner calling conventions for filename_create()
  namei: shift nameidata down into filename_parentat()
  namei: make filename_lookup() reject ERR_PTR() passed as name
  namei: shift nameidata inside filename_lookup()
  namei: move putname() call into filename_lookup()
  namei: pass the struct path to store the result down into path_lookupat()
  namei: uninline set_root{,_rcu}()
  namei: be careful with mountpoint crossings in follow_dotdot_rcu()
  Documentation: remove outdated information from automount-support.txt
  get rid of assorted nameidata-related debris
  lustre: kill unused helper
  lustre: kill unused macro (LOOKUP_CONTINUE)
  ...
parents b953c0d2 b853a161
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -50,8 +50,8 @@ prototypes:
	int (*rename2) (struct inode *, struct dentry *,
			struct inode *, struct dentry *, unsigned int);
	int (*readlink) (struct dentry *, char __user *,int);
	void * (*follow_link) (struct dentry *, struct nameidata *);
	void (*put_link) (struct dentry *, struct nameidata *, void *);
	const char *(*follow_link) (struct dentry *, void **);
	void (*put_link) (struct inode *, void *);
	void (*truncate) (struct inode *);
	int (*permission) (struct inode *, int, unsigned int);
	int (*get_acl)(struct inode *, int);
+13 −38
Original line number Diff line number Diff line
Support is available for filesystems that wish to do automounting support (such
as kAFS which can be found in fs/afs/). This facility includes allowing
in-kernel mounts to be performed and mountpoint degradation to be
requested. The latter can also be requested by userspace.
Support is available for filesystems that wish to do automounting
support (such as kAFS which can be found in fs/afs/ and NFS in
fs/nfs/). This facility includes allowing in-kernel mounts to be
performed and mountpoint degradation to be requested. The latter can
also be requested by userspace.


======================
IN-KERNEL AUTOMOUNTING
======================

A filesystem can now mount another filesystem on one of its directories by the
following procedure:

 (1) Give the directory a follow_link() operation.

     When the directory is accessed, the follow_link op will be called, and
     it will be provided with the location of the mountpoint in the nameidata
     structure (vfsmount and dentry).

 (2) Have the follow_link() op do the following steps:

     (a) Call vfs_kern_mount() to call the appropriate filesystem to set up a
         superblock and gain a vfsmount structure representing it.

     (b) Copy the nameidata provided as an argument and substitute the dentry
	 argument into it the copy.

     (c) Call do_add_mount() to install the new vfsmount into the namespace's
	 mountpoint tree, thus making it accessible to userspace. Use the
	 nameidata set up in (b) as the destination.

	 If the mountpoint will be automatically expired, then do_add_mount()
	 should also be given the location of an expiration list (see further
	 down).

     (d) Release the path in the nameidata argument and substitute in the new
	 vfsmount and its root dentry. The ref counts on these will need
	 incrementing.
See section "Mount Traps" of  Documentation/filesystems/autofs4.txt

Then from userspace, you can just do something like:

@@ -61,17 +35,18 @@ AUTOMATIC MOUNTPOINT EXPIRY
===========================

Automatic expiration of mountpoints is easy, provided you've mounted the
mountpoint to be expired in the automounting procedure outlined above.
mountpoint to be expired in the automounting procedure outlined separately.

To do expiration, you need to follow these steps:

 (3) Create at least one list off which the vfsmounts to be expired can be
     hung. Access to this list will be governed by the vfsmount_lock.
 (1) Create at least one list off which the vfsmounts to be expired can be
     hung.

 (4) In step (2c) above, the call to do_add_mount() should be provided with a
     pointer to this list. It will hang the vfsmount off of it if it succeeds.
 (2) When a new mountpoint is created in the ->d_automount method, add
     the mnt to the list using mnt_set_expiry()
             mnt_set_expiry(newmnt, &afs_vfsmounts);

 (5) When you want mountpoints to be expired, call mark_mounts_for_expiry()
 (3) When you want mountpoints to be expired, call mark_mounts_for_expiry()
     with a pointer to this list. This will process the list, marking every
     vfsmount thereon for potential expiry on the next call.

+17 −0
Original line number Diff line number Diff line
@@ -483,3 +483,20 @@ in your dentry operations instead.
--
[mandatory]
	->aio_read/->aio_write are gone.  Use ->read_iter/->write_iter.
---
[recommended]
	for embedded ("fast") symlinks just set inode->i_link to wherever the
	symlink body is and use simple_follow_link() as ->follow_link().
--
[mandatory]
	calling conventions for ->follow_link() have changed.  Instead of returning
	cookie and using nd_set_link() to store the body to traverse, we return
	the body to traverse and store the cookie using explicit void ** argument.
	nameidata isn't passed at all - nd_jump_link() doesn't need it and
	nd_[gs]et_link() is gone.
--
[mandatory]
	calling conventions for ->put_link() have changed.  It gets inode instead of
	dentry,  it does not get nameidata at all and it gets called only when cookie
	is non-NULL.  Note that link body isn't available anymore, so if you need it,
	store it as cookie.
+12 −10
Original line number Diff line number Diff line
@@ -350,8 +350,8 @@ struct inode_operations {
	int (*rename2) (struct inode *, struct dentry *,
			struct inode *, struct dentry *, unsigned int);
	int (*readlink) (struct dentry *, char __user *,int);
        void * (*follow_link) (struct dentry *, struct nameidata *);
        void (*put_link) (struct dentry *, struct nameidata *, void *);
	const char *(*follow_link) (struct dentry *, void **);
	void (*put_link) (struct inode *, void *);
	int (*permission) (struct inode *, int);
	int (*get_acl)(struct inode *, int);
	int (*setattr) (struct dentry *, struct iattr *);
@@ -436,16 +436,18 @@ otherwise noted.

  follow_link: called by the VFS to follow a symbolic link to the
	inode it points to.  Only required if you want to support
	symbolic links.  This method returns a void pointer cookie
	that is passed to put_link().
	symbolic links.  This method returns the symlink body
	to traverse (and possibly resets the current position with
	nd_jump_link()).  If the body won't go away until the inode
	is gone, nothing else is needed; if it needs to be otherwise
	pinned, the data needed to release whatever we'd grabbed
	is to be stored in void * variable passed by address to
	follow_link() instance.

  put_link: called by the VFS to release resources allocated by
  	follow_link().  The cookie returned by follow_link() is passed
  	to this method as the last parameter.  It is used by
  	filesystems such as NFS where page cache is not stable
  	(i.e. page that was installed when the symbolic link walk
  	started might not be in the page cache at the end of the
  	walk).
	follow_link().  The cookie stored by follow_link() is passed
	to this method as the last parameter; only called when
	cookie isn't NULL.

  permission: called by the VFS to check for access rights on a POSIX-like
  	filesystem.
+0 −15
Original line number Diff line number Diff line
@@ -189,22 +189,7 @@ static inline int ll_quota_off(struct super_block *sb, int off, int remount)
#endif



/*
 * After 3.1, kernel's nameidata.intent.open.flags is different
 * with lustre's lookup_intent.it_flags, as lustre's it_flags'
 * lower bits equal to FMODE_xxx while kernel doesn't transliterate
 * lower bits of nameidata.intent.open.flags to FMODE_xxx.
 * */
#include <linux/version.h>
static inline int ll_namei_to_lookup_intent_flag(int flag)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0)
	flag = (flag & ~O_ACCMODE) | OPEN_FMODE(flag);
#endif
	return flag;
}

#include <linux/fs.h>

# define ll_umode_t	umode_t
Loading