hc
2024-10-12 a5969cabbb4660eab42b6ef0412cbbd1200cf14d
kernel/fs/kernfs/file.c
....@@ -1,11 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * fs/kernfs/file.c - kernfs file implementation
34 *
45 * Copyright (c) 2001-3 Patrick Mochel
56 * Copyright (c) 2007 SUSE Linux Products GmbH
67 * Copyright (c) 2007, 2013 Tejun Heo <tj@kernel.org>
7
- *
8
- * This file is released under the GPLv2.
98 */
109
1110 #include <linux/fs.h>
....@@ -15,6 +14,7 @@
1514 #include <linux/pagemap.h>
1615 #include <linux/sched/mm.h>
1716 #include <linux/fsnotify.h>
17
+#include <linux/uio.h>
1818
1919 #include "kernfs-internal.h"
2020
....@@ -181,11 +181,10 @@
181181 * it difficult to use seq_file. Implement simplistic custom buffering for
182182 * bin files.
183183 */
184
-static ssize_t kernfs_file_direct_read(struct kernfs_open_file *of,
185
- char __user *user_buf, size_t count,
186
- loff_t *ppos)
184
+static ssize_t kernfs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
187185 {
188
- ssize_t len = min_t(size_t, count, PAGE_SIZE);
186
+ struct kernfs_open_file *of = kernfs_of(iocb->ki_filp);
187
+ ssize_t len = min_t(size_t, iov_iter_count(iter), PAGE_SIZE);
189188 const struct kernfs_ops *ops;
190189 char *buf;
191190
....@@ -211,7 +210,7 @@
211210 of->event = atomic_read(&of->kn->attr.open->event);
212211 ops = kernfs_ops(of->kn);
213212 if (ops->read)
214
- len = ops->read(of, buf, len, *ppos);
213
+ len = ops->read(of, buf, len, iocb->ki_pos);
215214 else
216215 len = -EINVAL;
217216
....@@ -221,12 +220,12 @@
221220 if (len < 0)
222221 goto out_free;
223222
224
- if (copy_to_user(user_buf, buf, len)) {
223
+ if (copy_to_iter(buf, len, iter) != len) {
225224 len = -EFAULT;
226225 goto out_free;
227226 }
228227
229
- *ppos += len;
228
+ iocb->ki_pos += len;
230229
231230 out_free:
232231 if (buf == of->prealloc_buf)
....@@ -236,31 +235,14 @@
236235 return len;
237236 }
238237
239
-/**
240
- * kernfs_fop_read - kernfs vfs read callback
241
- * @file: file pointer
242
- * @user_buf: data to write
243
- * @count: number of bytes
244
- * @ppos: starting offset
245
- */
246
-static ssize_t kernfs_fop_read(struct file *file, char __user *user_buf,
247
- size_t count, loff_t *ppos)
238
+static ssize_t kernfs_fop_read_iter(struct kiocb *iocb, struct iov_iter *iter)
248239 {
249
- struct kernfs_open_file *of = kernfs_of(file);
250
-
251
- if (of->kn->flags & KERNFS_HAS_SEQ_SHOW)
252
- return seq_read(file, user_buf, count, ppos);
253
- else
254
- return kernfs_file_direct_read(of, user_buf, count, ppos);
240
+ if (kernfs_of(iocb->ki_filp)->kn->flags & KERNFS_HAS_SEQ_SHOW)
241
+ return seq_read_iter(iocb, iter);
242
+ return kernfs_file_read_iter(iocb, iter);
255243 }
256244
257
-/**
258
- * kernfs_fop_write - kernfs vfs write callback
259
- * @file: file pointer
260
- * @user_buf: data to write
261
- * @count: number of bytes
262
- * @ppos: starting offset
263
- *
245
+/*
264246 * Copy data in from userland and pass it to the matching kernfs write
265247 * operation.
266248 *
....@@ -270,20 +252,18 @@
270252 * modify only the the value you're changing, then write entire buffer
271253 * back.
272254 */
273
-static ssize_t kernfs_fop_write(struct file *file, const char __user *user_buf,
274
- size_t count, loff_t *ppos)
255
+static ssize_t kernfs_fop_write_iter(struct kiocb *iocb, struct iov_iter *iter)
275256 {
276
- struct kernfs_open_file *of = kernfs_of(file);
257
+ struct kernfs_open_file *of = kernfs_of(iocb->ki_filp);
258
+ ssize_t len = iov_iter_count(iter);
277259 const struct kernfs_ops *ops;
278
- ssize_t len;
279260 char *buf;
280261
281262 if (of->atomic_write_len) {
282
- len = count;
283263 if (len > of->atomic_write_len)
284264 return -E2BIG;
285265 } else {
286
- len = min_t(size_t, count, PAGE_SIZE);
266
+ len = min_t(size_t, len, PAGE_SIZE);
287267 }
288268
289269 buf = of->prealloc_buf;
....@@ -294,7 +274,7 @@
294274 if (!buf)
295275 return -ENOMEM;
296276
297
- if (copy_from_user(buf, user_buf, len)) {
277
+ if (copy_from_iter(buf, len, iter) != len) {
298278 len = -EFAULT;
299279 goto out_free;
300280 }
....@@ -313,7 +293,7 @@
313293
314294 ops = kernfs_ops(of->kn);
315295 if (ops->write)
316
- len = ops->write(of, buf, len, *ppos);
296
+ len = ops->write(of, buf, len, iocb->ki_pos);
317297 else
318298 len = -EINVAL;
319299
....@@ -321,7 +301,7 @@
321301 mutex_unlock(&of->mutex);
322302
323303 if (len > 0)
324
- *ppos += len;
304
+ iocb->ki_pos += len;
325305
326306 out_free:
327307 if (buf == of->prealloc_buf)
....@@ -653,9 +633,9 @@
653633 * The following is done to give a different lockdep key to
654634 * @of->mutex for files which implement mmap. This is a rather
655635 * crude way to avoid false positive lockdep warning around
656
- * mm->mmap_sem - mmap nests @of->mutex under mm->mmap_sem and
636
+ * mm->mmap_lock - mmap nests @of->mutex under mm->mmap_lock and
657637 * reading /sys/block/sda/trace/act_mask grabs sr_mutex, under
658
- * which mm->mmap_sem nests, while holding @of->mutex. As each
638
+ * which mm->mmap_lock nests, while holding @of->mutex. As each
659639 * open file has a separate mutex, it's okay as long as those don't
660640 * happen on the same file. At this point, we can't easily give
661641 * each file a separate locking class. Let's differentiate on
....@@ -674,7 +654,7 @@
674654
675655 /*
676656 * Write path needs to atomic_write_len outside active reference.
677
- * Cache it in open_file. See kernfs_fop_write() for details.
657
+ * Cache it in open_file. See kernfs_fop_write_iter() for details.
678658 */
679659 of->atomic_write_len = ops->atomic_write_len;
680660
....@@ -884,7 +864,9 @@
884864
885865 list_for_each_entry(info, &kernfs_root(kn)->supers, node) {
886866 struct kernfs_node *parent;
867
+ struct inode *p_inode = NULL;
887868 struct inode *inode;
869
+ struct qstr name;
888870
889871 /*
890872 * We want fsnotify_modify() on @kn but as the
....@@ -892,26 +874,27 @@
892874 * have the matching @file available. Look up the inodes
893875 * and generate the events manually.
894876 */
895
- inode = ilookup(info->sb, kn->id.ino);
877
+ inode = ilookup(info->sb, kernfs_ino(kn));
896878 if (!inode)
897879 continue;
898880
881
+ name = (struct qstr)QSTR_INIT(kn->name, strlen(kn->name));
899882 parent = kernfs_get_parent(kn);
900883 if (parent) {
901
- struct inode *p_inode;
902
-
903
- p_inode = ilookup(info->sb, parent->id.ino);
884
+ p_inode = ilookup(info->sb, kernfs_ino(parent));
904885 if (p_inode) {
905
- fsnotify(p_inode, FS_MODIFY | FS_EVENT_ON_CHILD,
906
- inode, FSNOTIFY_EVENT_INODE, kn->name, 0);
886
+ fsnotify(FS_MODIFY | FS_EVENT_ON_CHILD,
887
+ inode, FSNOTIFY_EVENT_INODE,
888
+ p_inode, &name, inode, 0);
907889 iput(p_inode);
908890 }
909891
910892 kernfs_put(parent);
911893 }
912894
913
- fsnotify(inode, FS_MODIFY, inode, FSNOTIFY_EVENT_INODE,
914
- kn->name, 0);
895
+ if (!p_inode)
896
+ fsnotify_inode(inode, FS_MODIFY);
897
+
915898 iput(inode);
916899 }
917900
....@@ -958,14 +941,16 @@
958941 EXPORT_SYMBOL_GPL(kernfs_notify);
959942
960943 const struct file_operations kernfs_file_fops = {
961
- .read = kernfs_fop_read,
962
- .write = kernfs_fop_write,
944
+ .read_iter = kernfs_fop_read_iter,
945
+ .write_iter = kernfs_fop_write_iter,
963946 .llseek = generic_file_llseek,
964947 .mmap = kernfs_fop_mmap,
965948 .open = kernfs_fop_open,
966949 .release = kernfs_fop_release,
967950 .poll = kernfs_fop_poll,
968951 .fsync = noop_fsync,
952
+ .splice_read = generic_file_splice_read,
953
+ .splice_write = iter_file_splice_write,
969954 };
970955
971956 /**
....@@ -1009,7 +994,7 @@
1009994
1010995 #ifdef CONFIG_DEBUG_LOCK_ALLOC
1011996 if (key) {
1012
- lockdep_init_map(&kn->dep_map, "kn->count", key, 0);
997
+ lockdep_init_map(&kn->dep_map, "kn->active", key, 0);
1013998 kn->flags |= KERNFS_LOCKDEP;
1014999 }
10151000 #endif