From 517e64f57883bd63c5a4ab8b3d0d3ed68c55d0cf Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 28 Nov 2013 14:54:29 -0500 Subject: sysfs, kernfs: revamp sysfs_dirent active_ref lockdep annotation Currently, sysfs_dirent active_ref lockdep annotation uses attribute->[s]key as the lockdep key, which forces kernfs_create_file_ns() to assume that sysfs_dirent->priv is pointing to a struct attribute which may not be true for non-sysfs users. This patch restructures the lockdep annotation such that * kernfs_ops contains lockdep_key which is used by default for files created kernfs_create_file_ns(). * kernfs_create_file_ns_key() is introduced which takes an extra @key argument. The created file will use the specified key for active_ref lockdep annotation. If NULL is specified, lockdep for the file is disabled. * sysfs_add_file_mode_ns() is updated to use kernfs_create_file_ns_key() with the appropriate key from the attribute or NULL if ignore_lockdep is set. This makes the lockdep annotation properly contained in kernfs while allowing sysfs to cleanly keep its current behavior. This patch doesn't introduce any behavior differences. Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- include/linux/kernfs.h | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) (limited to 'include/linux/kernfs.h') diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h index f20796ecc76e..105d09dcb064 100644 --- a/include/linux/kernfs.h +++ b/include/linux/kernfs.h @@ -11,6 +11,7 @@ #include #include #include +#include struct file; struct iattr; @@ -62,6 +63,10 @@ struct kernfs_ops { loff_t off); int (*mmap)(struct sysfs_open_file *of, struct vm_area_struct *vma); + +#ifdef CONFIG_DEBUG_LOCK_ALLOC + struct lock_class_key lockdep_key; +#endif }; #ifdef CONFIG_SYSFS @@ -69,11 +74,12 @@ struct kernfs_ops { struct sysfs_dirent *kernfs_create_dir_ns(struct sysfs_dirent *parent, const char *name, void *priv, const void *ns); -struct sysfs_dirent *kernfs_create_file_ns(struct sysfs_dirent *parent, - const char *name, - umode_t mode, loff_t size, - const struct kernfs_ops *ops, - void *priv, const void *ns); +struct sysfs_dirent *kernfs_create_file_ns_key(struct sysfs_dirent *parent, + const char *name, + umode_t mode, loff_t size, + const struct kernfs_ops *ops, + void *priv, const void *ns, + struct lock_class_key *key); struct sysfs_dirent *kernfs_create_link(struct sysfs_dirent *parent, const char *name, struct sysfs_dirent *target); @@ -94,9 +100,10 @@ kernfs_create_dir_ns(struct sysfs_dirent *parent, const char *name, void *priv, { return ERR_PTR(-ENOSYS); } static inline struct sysfs_dirent * -kernfs_create_file_ns(struct sysfs_dirent *parent, const char *name, - umode_t mode, loff_t size, const struct kernfs_ops *ops, - void *priv, const void *ns) +kernfs_create_file_ns_key(struct sysfs_dirent *parent, const char *name, + umode_t mode, loff_t size, + const struct kernfs_ops *ops, void *priv, + const void *ns, struct lock_class_key *key) { return ERR_PTR(-ENOSYS); } static inline struct sysfs_dirent * @@ -131,6 +138,20 @@ kernfs_create_dir(struct sysfs_dirent *parent, const char *name, void *priv) return kernfs_create_dir_ns(parent, name, priv, NULL); } +static inline struct sysfs_dirent * +kernfs_create_file_ns(struct sysfs_dirent *parent, const char *name, + umode_t mode, loff_t size, const struct kernfs_ops *ops, + void *priv, const void *ns) +{ + struct lock_class_key *key = NULL; + +#ifdef CONFIG_DEBUG_LOCK_ALLOC + key = (struct lock_class_key *)&ops->lockdep_key; +#endif + return kernfs_create_file_ns_key(parent, name, mode, size, ops, priv, + ns, key); +} + static inline struct sysfs_dirent * kernfs_create_file(struct sysfs_dirent *parent, const char *name, umode_t mode, loff_t size, const struct kernfs_ops *ops, void *priv) -- cgit v1.2.2