diff options
Diffstat (limited to 'fs/kernfs/kernfs-internal.h')
| -rw-r--r-- | fs/kernfs/kernfs-internal.h | 16 | 
1 files changed, 12 insertions, 4 deletions
diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index 40a2a9cd819d..6061b6f70d2a 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h @@ -19,8 +19,6 @@  #include <linux/kernfs.h>  #include <linux/fs_context.h> -extern rwlock_t kernfs_rename_lock; -  struct kernfs_iattrs {  	kuid_t			ia_uid;  	kgid_t			ia_gid; @@ -40,6 +38,7 @@ struct kernfs_root {  	/* private fields, do not use outside kernfs proper */  	struct idr		ino_idr; +	spinlock_t		kernfs_idr_lock;	/* root->ino_idr */  	u32			last_id_lowbits;  	u32			id_highbits;  	struct kernfs_syscall_ops *syscall_ops; @@ -52,6 +51,9 @@ struct kernfs_root {  	struct rw_semaphore	kernfs_iattr_rwsem;  	struct rw_semaphore	kernfs_supers_rwsem; +	/* kn->parent and kn->name */ +	rwlock_t		kernfs_rename_lock; +  	struct rcu_head		rcu;  }; @@ -107,6 +109,11 @@ static inline bool kernfs_root_is_locked(const struct kernfs_node *kn)  	return lockdep_is_held(&kernfs_root(kn)->kernfs_rwsem);  } +static inline bool kernfs_rename_is_locked(const struct kernfs_node *kn) +{ +	return lockdep_is_held(&kernfs_root(kn)->kernfs_rename_lock); +} +  static inline const char *kernfs_rcu_name(const struct kernfs_node *kn)  {  	return rcu_dereference_check(kn->name, kernfs_root_is_locked(kn)); @@ -117,14 +124,15 @@ static inline struct kernfs_node *kernfs_parent(const struct kernfs_node *kn)  	/*  	 * The kernfs_node::__parent remains valid within a RCU section. The kn  	 * can be reparented (and renamed) which changes the entry. This can be -	 * avoided by locking kernfs_root::kernfs_rwsem or kernfs_rename_lock. +	 * avoided by locking kernfs_root::kernfs_rwsem or +	 * kernfs_root::kernfs_rename_lock.  	 * Both locks can be used to obtain a reference on __parent. Once the  	 * reference count reaches 0 then the node is about to be freed  	 * and can not be renamed (or become a different parent) anymore.  	 */  	return rcu_dereference_check(kn->__parent,  				     kernfs_root_is_locked(kn) || -				     lockdep_is_held(&kernfs_rename_lock) || +				     kernfs_rename_is_locked(kn) ||  				     !atomic_read(&kn->count));  }  | 
