aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysfs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/sysfs/file.c')
-rw-r--r--fs/sysfs/file.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 79b5da2acbe1..b94f93685093 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -609,7 +609,7 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
609 struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; 609 struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
610 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; 610 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
611 struct sysfs_open_file *of; 611 struct sysfs_open_file *of;
612 bool has_read, has_write; 612 bool has_read, has_write, has_mmap;
613 int error = -EACCES; 613 int error = -EACCES;
614 614
615 /* need attr_sd for attr and ops, its parent for kobj */ 615 /* need attr_sd for attr and ops, its parent for kobj */
@@ -621,6 +621,7 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
621 621
622 has_read = battr->read || battr->mmap; 622 has_read = battr->read || battr->mmap;
623 has_write = battr->write || battr->mmap; 623 has_write = battr->write || battr->mmap;
624 has_mmap = battr->mmap;
624 } else { 625 } else {
625 const struct sysfs_ops *ops = sysfs_file_ops(attr_sd); 626 const struct sysfs_ops *ops = sysfs_file_ops(attr_sd);
626 627
@@ -632,6 +633,7 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
632 633
633 has_read = ops->show; 634 has_read = ops->show;
634 has_write = ops->store; 635 has_write = ops->store;
636 has_mmap = false;
635 } 637 }
636 638
637 /* check perms and supported operations */ 639 /* check perms and supported operations */
@@ -649,7 +651,23 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
649 if (!of) 651 if (!of)
650 goto err_out; 652 goto err_out;
651 653
652 mutex_init(&of->mutex); 654 /*
655 * The following is done to give a different lockdep key to
656 * @of->mutex for files which implement mmap. This is a rather
657 * crude way to avoid false positive lockdep warning around
658 * mm->mmap_sem - mmap nests @of->mutex under mm->mmap_sem and
659 * reading /sys/block/sda/trace/act_mask grabs sr_mutex, under
660 * which mm->mmap_sem nests, while holding @of->mutex. As each
661 * open file has a separate mutex, it's okay as long as those don't
662 * happen on the same file. At this point, we can't easily give
663 * each file a separate locking class. Let's differentiate on
664 * whether the file has mmap or not for now.
665 */
666 if (has_mmap)
667 mutex_init(&of->mutex);
668 else
669 mutex_init(&of->mutex);
670
653 of->sd = attr_sd; 671 of->sd = attr_sd;
654 of->file = file; 672 of->file = file;
655 673