Explorar o código

Merge tag 'driver-core-4.8-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core

Pull driver core fixes from Greg KH:
 "Here are three small fixes for 4.8-rc5.

  One for sysfs, one for kernfs, and one documentation fix, all for
  reported issues.  All of these have been in linux-next for a while"

* tag 'driver-core-4.8-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core:
  sysfs: correctly handle read offset on PREALLOC attrs
  documentation: drivers/core/of: fix name of of_node symlink
  kernfs: don't depend on d_find_any_alias() when generating notifications
Linus Torvalds %!s(int64=9) %!d(string=hai) anos
pai
achega
41488202f1
Modificáronse 3 ficheiros con 29 adicións e 9 borrados
  1. 1 1
      Documentation/ABI/stable/sysfs-devices
  2. 21 7
      fs/kernfs/file.c
  3. 7 1
      fs/sysfs/file.c

+ 1 - 1
Documentation/ABI/stable/sysfs-devices

@@ -1,7 +1,7 @@
 # Note: This documents additional properties of any device beyond what
 # Note: This documents additional properties of any device beyond what
 # is documented in Documentation/sysfs-rules.txt
 # is documented in Documentation/sysfs-rules.txt
 
 
-What:		/sys/devices/*/of_path
+What:		/sys/devices/*/of_node
 Date:		February 2015
 Date:		February 2015
 Contact:	Device Tree mailing list <devicetree@vger.kernel.org>
 Contact:	Device Tree mailing list <devicetree@vger.kernel.org>
 Description:
 Description:

+ 21 - 7
fs/kernfs/file.c

@@ -840,21 +840,35 @@ repeat:
 	mutex_lock(&kernfs_mutex);
 	mutex_lock(&kernfs_mutex);
 
 
 	list_for_each_entry(info, &kernfs_root(kn)->supers, node) {
 	list_for_each_entry(info, &kernfs_root(kn)->supers, node) {
+		struct kernfs_node *parent;
 		struct inode *inode;
 		struct inode *inode;
-		struct dentry *dentry;
 
 
+		/*
+		 * We want fsnotify_modify() on @kn but as the
+		 * modifications aren't originating from userland don't
+		 * have the matching @file available.  Look up the inodes
+		 * and generate the events manually.
+		 */
 		inode = ilookup(info->sb, kn->ino);
 		inode = ilookup(info->sb, kn->ino);
 		if (!inode)
 		if (!inode)
 			continue;
 			continue;
 
 
-		dentry = d_find_any_alias(inode);
-		if (dentry) {
-			fsnotify_parent(NULL, dentry, FS_MODIFY);
-			fsnotify(inode, FS_MODIFY, inode, FSNOTIFY_EVENT_INODE,
-				 NULL, 0);
-			dput(dentry);
+		parent = kernfs_get_parent(kn);
+		if (parent) {
+			struct inode *p_inode;
+
+			p_inode = ilookup(info->sb, parent->ino);
+			if (p_inode) {
+				fsnotify(p_inode, FS_MODIFY | FS_EVENT_ON_CHILD,
+					 inode, FSNOTIFY_EVENT_INODE, kn->name, 0);
+				iput(p_inode);
+			}
+
+			kernfs_put(parent);
 		}
 		}
 
 
+		fsnotify(inode, FS_MODIFY, inode, FSNOTIFY_EVENT_INODE,
+			 kn->name, 0);
 		iput(inode);
 		iput(inode);
 	}
 	}
 
 

+ 7 - 1
fs/sysfs/file.c

@@ -114,9 +114,15 @@ static ssize_t sysfs_kf_read(struct kernfs_open_file *of, char *buf,
 	 * If buf != of->prealloc_buf, we don't know how
 	 * If buf != of->prealloc_buf, we don't know how
 	 * large it is, so cannot safely pass it to ->show
 	 * large it is, so cannot safely pass it to ->show
 	 */
 	 */
-	if (pos || WARN_ON_ONCE(buf != of->prealloc_buf))
+	if (WARN_ON_ONCE(buf != of->prealloc_buf))
 		return 0;
 		return 0;
 	len = ops->show(kobj, of->kn->priv, buf);
 	len = ops->show(kobj, of->kn->priv, buf);
+	if (pos) {
+		if (len <= pos)
+			return 0;
+		len -= pos;
+		memmove(buf, buf + pos, len);
+	}
 	return min(count, len);
 	return min(count, len);
 }
 }