History

Merge tag 'vfs-7.2-rc2.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull vfs fixes from Christian Brauner: - netfs: - fix the decision when to disallow write-streaming with fscache in use, handling of asynchronous cache object creation, a double fput in cachefiles, clearing S_KERNEL_FILE without the inode lock held, page extraction bugs in the iov_iter helpers (a potential underflow, a missing allocation failure check, a memory leak, and a folio offset miscalculation), writeback error and ENOMEM handling, DIO write retry for filesystems without a ->prepare_write() method, and the replacement of the wb_lock mutex with a bit lock plus writethrough collection offload so that multiple asynchronous writebacks don't interfere with each other. - Fix the barriering when walking the netfs subrequest list during retries as it was possible to see a subrequest that was just added by the application thread. - iomap: - Change iomap to submit read bios after each extent instead of building them up across extents. The old behavior was considered problematic for a while and now caused an actual erofs bug. - Guard the ioend io_size EOF trim in iomap against underflow when a concurrent truncate moves EOF below the start of the ioend, wrapping io_size to a huge value. - overlayfs - Fix a stale overlayfs comment about the locking order. - Store the linked-in upper dentry instead of the disconnected O_TMPFILE dentry during overlayfs tmpfile copy-up. With a FUSE or virtiofs upper layer ->d_revalidate() would try to look up "/" in the workdir and fail, causing persistent ESTALE errors that broke dpkg and apt. - vfs-bpf: Have the bpf_real_data_inode() kfunc take a struct file instead of a dentry so it is usable from the bprm_check_security, mmap_file, and file_mprotect hooks, and rename it from bpf_real_inode() to make the data-inode semantics explicit. The kfunc landed this cycle so the change is safe. - afs: NULL pointer dereferences in the callback service and in afs_get_tree(), several memory and refcount leaks, missing locking around the dynamic root inode numbers and premature cell exposure through /afs, a netns destruction hang caused by a misplaced increment of net->cells_outstanding, a bulk lookup malfunction caused by the dir_emit() API change, inode (re)initialisation issues, and assorted smaller fixes to error codes, seqlock handling, and debug output. - vfs: Refuse O_TMPFILE creation with an unmapped fsuid or fsgid and add a selftest for it. - vboxsf: Add Jori Koolstra as vboxsf maintainer, taking over from Hans de Goede. - dio: Release the pages attached to a short atomic dio bio; the REQ_ATOMIC size check error path leaked them. - procfs: Only bump the parent directory link count when registering directories in procfs. Registering regular files inflated the count and leaked a link on every create and remove cycle. - minix: Avoid an unsigned overflow in the minix bitmap block count calculation that let crafted images with huge inode or zone counts pass superblock validation and crash the kernel during mount. - cachefiles: Fix a double unlock in the cachefiles nomem_d_alloc error path left over from the start_creating() conversion. - fat: Stop fat from reading directory entries past the 0x00 end-of-directory marker. If the trailing on-disk slots aren't zero-filled the driver surfaced arbitrary garbage as directory entries. - freexvfs: Don't BUG() on unknown typed-extent types in freevxfs, reachable via ioctl(FIBMAP) on a crafted image; fail with an I/O error instead. - orangefs: Keep the readdir entry size 64-bit in orangefs fill_from_part(). Truncating it to __u32 bypassed the bounds check and led to out-of-bounds reads triggerable by the userspace client. - xfs: Fix the error unwind in xfs_open_devices() which released the rt device file twice and left dangling buftarg pointers behind that were freed again when the failed mount was torn down. - exec: Fix an off-by-one in the comment documenting the maximum binfmt rewrite depth in exec_binprm(). The code allows five rewrites, not four; restricting the code would break userspace so the comment is fixed instead. - file handles: Reject detached mounts in capable_wrt_mount(). A detached mount can be dissolved concurrently, leaving a NULL mount namespace that open_by_handle_at() would dereference. * tag 'vfs-7.2-rc2.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (57 commits) netfs: Fix barriering when walking subrequest list iomap: submit read bio after each extent fuse: call fuse_send_readpages explicitly from fuse_readahead iomap: consolidate bio submission fhandle: reject detached mounts in capable_wrt_mount() netfs: Fix DIO write retry for filesystems without a ->prepare_write() netfs: Fix folio state after ENOMEM whilst under writeback iteration netfs: Fix writeback error handling netfs: Fix writethrough to use collection offload netfs: Replace wb_lock with a bit lock for asynchronicity netfs: Fix kdoc warning scatterlist: Fix offset in folio calc in extract_xarray_to_sg() iov_iter: Remove unused variable in kunit_iov_iter.c iov_iter: Fix a memory leak in iov_iter_extract_user_pages() iov_iter: Fix missing alloc fail check in iov_iter_extract_bvec_pages() iov_iter: Fix potential underflow in iov_iter_extract_xarray_pages() cachefiles: Fix file burial to take lock when unsetting S_KERNEL_FILE cachefiles: Fix double fput netfs: Fix netfs_create_write_req() to handle async cache object creation netfs: Fix decision whether to disallow write-streaming due to fscache use ...

Linus Torvalds committed 4 months ago

Commit 71dfdfb2 parents 025d0d6 5c6ce0552 files · +592 −178Browse files

Unified · Split

52 files
  1. MAINTAINERS +1 −1
  2. fs/afs/callback.c +7 −10
  3. fs/afs/cell.c +21 −6
  4. fs/afs/cmservice.c +5 −2
  5. fs/afs/dir.c +25 −15
  6. fs/afs/dynroot.c +1 −1
  7. fs/afs/fs_operation.c +1 −1
  8. fs/afs/inode.c +7 −8
  9. fs/afs/internal.h +1 −2
  10. fs/afs/super.c +3 −2
  11. fs/afs/symlink.c +2 −2
  12. fs/afs/vl_list.c +21 −3
  13. fs/afs/volume.c +1 −1
  14. fs/bpf_fs_kfuncs.c +14 −9
  15. fs/cachefiles/namei.c +1 −3
  16. fs/exec.c +1 −1
  17. fs/exfat/iomap.c +1 −4
  18. fs/fat/dir.c +40 −4
  19. fs/fhandle.c +1 −1
  20. fs/freevxfs/vxfs_bmap.c +2 −1
  21. fs/fuse/file.c +3 −11
  22. fs/iomap/bio.c +12 −3
  23. fs/iomap/buffered-io.c +8 −8
  24. fs/iomap/direct-io.c +6 −1
  25. fs/iomap/ioend.c +6 −2
  26. fs/minix/minix.h +1 −1
  27. fs/namei.c +4 −0
  28. fs/netfs/buffered_read.c +1 −1
  29. fs/netfs/buffered_write.c +1 −1
  30. fs/netfs/direct_write.c +7 −11
  31. fs/netfs/internal.h +12 −0
  32. fs/netfs/locking.c +95 −0
  33. fs/netfs/read_retry.c +6 −1
  34. fs/netfs/write_collect.c +10 −0
  35. fs/netfs/write_issue.c +24 −31
  36. fs/netfs/write_retry.c +6 −1
  37. fs/ntfs/aops.c +2 −4
  38. fs/ntfs3/inode.c +1 −4
  39. fs/orangefs/dir.c +4 −3
  40. fs/overlayfs/copy_up.c +10 −2
  41. fs/overlayfs/inode.c +2 −2
  42. fs/proc/generic.c +4 −5
  43. fs/xfs/xfs_aops.c +1 −2
  44. fs/xfs/xfs_super.c +3 −0
  45. include/linux/iomap.h +2 −0
  46. include/linux/netfs.h +10 −3
  47. lib/iov_iter.c +19 −1
  48. lib/scatterlist.c +1 −0
  49. lib/tests/kunit_iov_iter.c +2 −3
  50. tools/testing/selftests/filesystems/.gitignore +1 −0
  51. tools/testing/selftests/filesystems/Makefile +4 −0
  52. tools/testing/selftests/filesystems/idmapped_tmpfile.c +168 −0
MAINTAINERS+1−1
@@ -28725,7 +28725,7 @@ F: include/linux/vbox_utils.h · 28724 unmodified lines
28725F: include/uapi/linux/vbox*.h28725F: include/uapi/linux/vbox*.h
28726 28726
28727VIRTUAL BOX SHARED FOLDER VFS DRIVER28727VIRTUAL BOX SHARED FOLDER VFS DRIVER
28728M: Hans de Goede <hansg@kernel.org>28728M: Jori Koolstra <jkoolstra@xs4all.nl>
28729L: linux-fsdevel@vger.kernel.org28729L: linux-fsdevel@vger.kernel.org
28730S: Maintained28730S: Maintained
28731F: fs/vboxsf/*28731F: fs/vboxsf/*
fs/afs/callback.c+7−10
@@ -113,16 +113,12 @@ static struct afs_volume *afs_lookup_volume_rcu(struct afs_cell *cell, · 112 unmodified lines
113{113{
114 struct afs_volume *volume = NULL;114 struct afs_volume *volume = NULL;
115 struct rb_node *p;115 struct rb_node *p;
116 int seq = 1;
117 116
118 for (;;) {117 scoped_seqlock_read(&cell->volume_lock, ss_lock) {
119 /* Unfortunately, rbtree walking doesn't give reliable results118 /* Unfortunately, rbtree walking doesn't give reliable results
120 * under just the RCU read lock, so we have to check for119 * under just the RCU read lock, so we have to check for
121 * changes.120 * changes.
122 */121 */
123 seq++; /* 2 on the 1st/lockless path, otherwise odd */
124 read_seqbegin_or_lock(&cell->volume_lock, &seq);
125
126 p = rcu_dereference_raw(cell->volumes.rb_node);122 p = rcu_dereference_raw(cell->volumes.rb_node);
127 while (p) {123 while (p) {
128 volume = rb_entry(p, struct afs_volume, cell_node);124 volume = rb_entry(p, struct afs_volume, cell_node);
@@ -138,12 +134,9 @@ static struct afs_volume *afs_lookup_volume_rcu(struct afs_cell *cell, · 9 unmodified lines
138 134
139 if (volume && afs_try_get_volume(volume, afs_volume_trace_get_callback))135 if (volume && afs_try_get_volume(volume, afs_volume_trace_get_callback))
140 break;136 break;
141 if (!need_seqretry(&cell->volume_lock, seq))137 volume = NULL;
142 break;
143 seq |= 1; /* Want a lock next time */
144 }138 }
145 139
146 done_seqretry(&cell->volume_lock, seq);
147 return volume;140 return volume;
148}141}
149 142
@@ -221,7 +214,11 @@ static void afs_break_some_callbacks(struct afs_server *server, · 71 unmodified lines
221 214
222 rcu_read_lock();215 rcu_read_lock();
223 volume = afs_lookup_volume_rcu(server->cell, vid);216 volume = afs_lookup_volume_rcu(server->cell, vid);
224 if (cbb->fid.vnode == 0 && cbb->fid.unique == 0) {217 if (!volume) {
218 /* Ignore breaks on unknown volumes. */
219 rcu_read_unlock();
220 *_count = 0;
221 } else if (cbb->fid.vnode == 0 && cbb->fid.unique == 0) {
225 afs_break_volume_callback(server, volume);222 afs_break_volume_callback(server, volume);
226 *_count -= 1;223 *_count -= 1;
227 if (*_count)224 if (*_count)
fs/afs/cell.c+21−6
@@ -206,11 +206,6 @@ static struct afs_cell *afs_alloc_cell(struct afs_net *net, · 205 unmodified lines
206 cell->dns_status = vllist->status;206 cell->dns_status = vllist->status;
207 smp_store_release(&cell->dns_lookup_count, 1); /* vs source/status */207 smp_store_release(&cell->dns_lookup_count, 1); /* vs source/status */
208 atomic_inc(&net->cells_outstanding);208 atomic_inc(&net->cells_outstanding);
209 ret = idr_alloc_cyclic(&net->cells_dyn_ino, cell,
210 2, INT_MAX / 2, GFP_KERNEL);
211 if (ret < 0)
212 goto error;
213 cell->dynroot_ino = ret;
214 cell->debug_id = atomic_inc_return(&cell_debug_id);209 cell->debug_id = atomic_inc_return(&cell_debug_id);
215 210
216 trace_afs_cell(cell->debug_id, 1, 0, afs_cell_trace_alloc);211 trace_afs_cell(cell->debug_id, 1, 0, afs_cell_trace_alloc);
@@ -304,6 +299,13 @@ struct afs_cell *afs_lookup_cell(struct afs_net *net, · 87 unmodified lines
304 goto cell_already_exists;299 goto cell_already_exists;
305 }300 }
306 301
302 ret = idr_alloc_cyclic(&net->cells_dyn_ino, candidate,
303 2, INT_MAX / 2, GFP_KERNEL);
304 if (ret < 0)
305 goto cant_alloc_ino;
306 candidate->dynroot_ino = ret;
307 set_bit(AFS_CELL_FL_HAVE_INO, &candidate->flags);
308
307 cell = candidate;309 cell = candidate;
308 candidate = NULL;310 candidate = NULL;
309 afs_use_cell(cell, trace);311 afs_use_cell(cell, trace);
@@ -378,6 +380,11 @@ no_wait: · 68 unmodified lines
378 _leave(" = %p [cell]", cell);380 _leave(" = %p [cell]", cell);
379 return cell;381 return cell;
380 382
383cant_alloc_ino:
384 up_write(&net->cells_lock);
385 afs_put_cell(candidate, afs_cell_trace_put_candidate);
386 goto error_noput;
387
381cell_already_exists:388cell_already_exists:
382 _debug("cell exists");389 _debug("cell exists");
383 cell = cursor;390 cell = cursor;
@@ -547,6 +554,8 @@ static int afs_update_cell(struct afs_cell *cell) · 163 unmodified lines
547 rcu_assign_pointer(cell->vl_servers, vllist);554 rcu_assign_pointer(cell->vl_servers, vllist);
548 cell->dns_source = vllist->source;555 cell->dns_source = vllist->source;
549 old = p;556 old = p;
557 } else {
558 old = vllist;
550 }559 }
551 write_unlock(&cell->vl_servers_lock);560 write_unlock(&cell->vl_servers_lock);
552 afs_put_vlserverlist(cell->net, old);561 afs_put_vlserverlist(cell->net, old);
@@ -577,7 +586,6 @@ static void afs_cell_destroy(struct rcu_head *rcu) · 24 unmodified lines
577 afs_put_vlserverlist(net, rcu_access_pointer(cell->vl_servers));586 afs_put_vlserverlist(net, rcu_access_pointer(cell->vl_servers));
578 afs_unuse_cell(cell->alias_of, afs_cell_trace_unuse_alias);587 afs_unuse_cell(cell->alias_of, afs_cell_trace_unuse_alias);
579 key_put(cell->anonymous_key);588 key_put(cell->anonymous_key);
580 idr_remove(&net->cells_dyn_ino, cell->dynroot_ino);
581 kfree(cell->name - 1);589 kfree(cell->name - 1);
582 kfree(cell);590 kfree(cell);
583 591
@@ -592,6 +600,13 @@ static void afs_destroy_cell_work(struct work_struct *work) · 8 unmodified lines
592 afs_see_cell(cell, afs_cell_trace_destroy);600 afs_see_cell(cell, afs_cell_trace_destroy);
593 timer_delete_sync(&cell->management_timer);601 timer_delete_sync(&cell->management_timer);
594 cancel_work_sync(&cell->manager);602 cancel_work_sync(&cell->manager);
603
604 if (test_bit(AFS_CELL_FL_HAVE_INO, &cell->flags)) {
605 down_write(&cell->net->cells_lock);
606 idr_remove(&cell->net->cells_dyn_ino, cell->dynroot_ino);
607 up_write(&cell->net->cells_lock);
608 }
609
595 call_rcu(&cell->rcu, afs_cell_destroy);610 call_rcu(&cell->rcu, afs_cell_destroy);
596}611}
597 612
fs/afs/cmservice.c+5−2
@@ -334,7 +334,6 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call) · 333 unmodified lines
334 ret = afs_extract_data(call, false);334 ret = afs_extract_data(call, false);
335 switch (ret) {335 switch (ret) {
336 case 0: break;336 case 0: break;
337 case -EAGAIN: return 0;
338 default: return ret;337 default: return ret;
339 }338 }
340 339
@@ -364,6 +363,11 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call) · 23 unmodified lines
364 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))363 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
365 return afs_io_error(call, afs_io_error_cm_reply);364 return afs_io_error(call, afs_io_error_cm_reply);
366 365
366 if (!call->server) {
367 trace_afs_cm_no_server_u(call, call->request);
368 return 0;
369 }
370
367 if (memcmp(call->request, &call->server->_uuid, sizeof(call->server->_uuid)) != 0) {371 if (memcmp(call->request, &call->server->_uuid, sizeof(call->server->_uuid)) != 0) {
368 pr_notice("Callback UUID does not match fileserver UUID\n");372 pr_notice("Callback UUID does not match fileserver UUID\n");
369 trace_afs_cm_no_server_u(call, call->request);373 trace_afs_cm_no_server_u(call, call->request);
@@ -451,7 +455,6 @@ static int afs_deliver_cb_probe_uuid(struct afs_call *call) · 81 unmodified lines
451 ret = afs_extract_data(call, false);455 ret = afs_extract_data(call, false);
452 switch (ret) {456 switch (ret) {
453 case 0: break;457 case 0: break;
454 case -EAGAIN: return 0;
455 default: return ret;458 default: return ret;
456 }459 }
457 460
fs/afs/dir.c+25−15
@@ -28,9 +28,11 @@ static int afs_d_revalidate(struct inode *dir, const struct qstr *name, · 27 unmodified lines
28static int afs_d_delete(const struct dentry *dentry);28static int afs_d_delete(const struct dentry *dentry);
29static void afs_d_iput(struct dentry *dentry, struct inode *inode);29static void afs_d_iput(struct dentry *dentry, struct inode *inode);
30static bool afs_lookup_one_filldir(struct dir_context *ctx, const char *name, int nlen,30static bool afs_lookup_one_filldir(struct dir_context *ctx, const char *name, int nlen,
31 loff_t fpos, u64 ino, unsigned dtype);31 u64 ino, u32 uniquifier);
32#define AFS_LOOKUP_ONE ((filldir_t)0x123UL)
32static bool afs_lookup_filldir(struct dir_context *ctx, const char *name, int nlen,33static bool afs_lookup_filldir(struct dir_context *ctx, const char *name, int nlen,
33 loff_t fpos, u64 ino, unsigned dtype);34 u64 ino, u32 uniquifier);
35#define AFS_LOOKUP ((filldir_t)0x137UL)
34static int afs_create(struct mnt_idmap *idmap, struct inode *dir,36static int afs_create(struct mnt_idmap *idmap, struct inode *dir,
35 struct dentry *dentry, umode_t mode, bool excl);37 struct dentry *dentry, umode_t mode, bool excl);
36static struct dentry *afs_mkdir(struct mnt_idmap *idmap, struct inode *dir,38static struct dentry *afs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
@@ -421,11 +423,18 @@ static int afs_dir_iterate_block(struct afs_vnode *dvnode, · 384 unmodified lines
421 }423 }
422 424
423 /* found the next entry */425 /* found the next entry */
424 if (!dir_emit(ctx, dire->u.name, nlen,426 if (ctx->actor == AFS_LOOKUP) {
425 ntohl(dire->u.vnode),427 if (!afs_lookup_filldir(ctx, dire->u.name, nlen,
426 (ctx->actor == afs_lookup_filldir ||428 ntohl(dire->u.vnode),
427 ctx->actor == afs_lookup_one_filldir)?429 ntohl(dire->u.unique)))
428 ntohl(dire->u.unique) : DT_UNKNOWN)) {430 return 0;
431 } else if (ctx->actor == AFS_LOOKUP_ONE) {
432 if (!afs_lookup_one_filldir(ctx, dire->u.name, nlen,
433 ntohl(dire->u.vnode),
434 ntohl(dire->u.unique)))
435 return 0;
436 } else if (!dir_emit(ctx, dire->u.name, nlen,
437 ntohl(dire->u.vnode), DT_UNKNOWN)) {
429 _leave(" = 0 [full]");438 _leave(" = 0 [full]");
430 return 0;439 return 0;
431 }440 }
@@ -545,6 +554,7 @@ static int afs_readdir(struct file *file, struct dir_context *ctx) · 113 unmodified lines
545{554{
546 afs_dataversion_t dir_version;555 afs_dataversion_t dir_version;
547 556
557 ctx->dt_flags_mask = UINT_MAX;
548 return afs_dir_iterate(file_inode(file), ctx, file, &dir_version);558 return afs_dir_iterate(file_inode(file), ctx, file, &dir_version);
549}559}
550 560
@@ -554,14 +564,14 @@ static int afs_readdir(struct file *file, struct dir_context *ctx) · 3 unmodified lines
554 * uniquifier through dtype564 * uniquifier through dtype
555 */565 */
556static bool afs_lookup_one_filldir(struct dir_context *ctx, const char *name,566static bool afs_lookup_one_filldir(struct dir_context *ctx, const char *name,
557 int nlen, loff_t fpos, u64 ino, unsigned dtype)567 int nlen, u64 ino, u32 uniquifier)
558{568{
559 struct afs_lookup_one_cookie *cookie =569 struct afs_lookup_one_cookie *cookie =
560 container_of(ctx, struct afs_lookup_one_cookie, ctx);570 container_of(ctx, struct afs_lookup_one_cookie, ctx);
561 571
562 _enter("{%s,%u},%s,%u,,%llu,%u",572 _enter("{%s,%u},%s,%u,,%llu,%u",
563 cookie->name.name, cookie->name.len, name, nlen,573 cookie->name.name, cookie->name.len, name, nlen,
564 (unsigned long long) ino, dtype);574 (unsigned long long) ino, uniquifier);
565 575
566 /* insanity checks first */576 /* insanity checks first */
567 BUILD_BUG_ON(sizeof(union afs_xdr_dir_block) != 2048);577 BUILD_BUG_ON(sizeof(union afs_xdr_dir_block) != 2048);
@@ -574,7 +584,7 @@ static bool afs_lookup_one_filldir(struct dir_context *ctx, const char *name, · 6 unmodified lines
574 }584 }
575 585
576 cookie->fid.vnode = ino;586 cookie->fid.vnode = ino;
577 cookie->fid.unique = dtype;587 cookie->fid.unique = uniquifier;
578 cookie->found = 1;588 cookie->found = 1;
579 589
580 _leave(" = false [found]");590 _leave(" = false [found]");
@@ -591,7 +601,7 @@ static int afs_do_lookup_one(struct inode *dir, const struct qstr *name, · 10 unmodified lines
591{601{
592 struct afs_super_info *as = dir->i_sb->s_fs_info;602 struct afs_super_info *as = dir->i_sb->s_fs_info;
593 struct afs_lookup_one_cookie cookie = {603 struct afs_lookup_one_cookie cookie = {
594 .ctx.actor = afs_lookup_one_filldir,604 .ctx.actor = AFS_LOOKUP_ONE,
595 .name = *name,605 .name = *name,
596 .fid.vid = as->volume->vid606 .fid.vid = as->volume->vid
597 };607 };
@@ -622,14 +632,14 @@ static int afs_do_lookup_one(struct inode *dir, const struct qstr *name, · 24 unmodified lines
622 * uniquifier through dtype632 * uniquifier through dtype
623 */633 */
624static bool afs_lookup_filldir(struct dir_context *ctx, const char *name,634static bool afs_lookup_filldir(struct dir_context *ctx, const char *name,
625 int nlen, loff_t fpos, u64 ino, unsigned dtype)635 int nlen, u64 ino, u32 uniquifier)
626{636{
627 struct afs_lookup_cookie *cookie =637 struct afs_lookup_cookie *cookie =
628 container_of(ctx, struct afs_lookup_cookie, ctx);638 container_of(ctx, struct afs_lookup_cookie, ctx);
629 639
630 _enter("{%s,%u},%s,%u,,%llu,%u",640 _enter("{%s,%u},%s,%u,,%llu,%u",
631 cookie->name.name, cookie->name.len, name, nlen,641 cookie->name.name, cookie->name.len, name, nlen,
632 (unsigned long long) ino, dtype);642 (unsigned long long) ino, uniquifier);
633 643
634 /* insanity checks first */644 /* insanity checks first */
635 BUILD_BUG_ON(sizeof(union afs_xdr_dir_block) != 2048);645 BUILD_BUG_ON(sizeof(union afs_xdr_dir_block) != 2048);
@@ -637,7 +647,7 @@ static bool afs_lookup_filldir(struct dir_context *ctx, const char *name, · 1 unmodified line
637 647
638 if (cookie->nr_fids < 50) {648 if (cookie->nr_fids < 50) {
639 cookie->fids[cookie->nr_fids].vnode = ino;649 cookie->fids[cookie->nr_fids].vnode = ino;
640 cookie->fids[cookie->nr_fids].unique = dtype;650 cookie->fids[cookie->nr_fids].unique = uniquifier;
641 cookie->nr_fids++;651 cookie->nr_fids++;
642 }652 }
643 653
@@ -778,7 +788,7 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry) · 134 unmodified lines
778 788
779 for (i = 0; i < ARRAY_SIZE(cookie->fids); i++)789 for (i = 0; i < ARRAY_SIZE(cookie->fids); i++)
780 cookie->fids[i].vid = dvnode->fid.vid;790 cookie->fids[i].vid = dvnode->fid.vid;
781 cookie->ctx.actor = afs_lookup_filldir;791 cookie->ctx.actor = AFS_LOOKUP;
782 cookie->name = dentry->d_name;792 cookie->name = dentry->d_name;
783 cookie->nr_fids = 2; /* slot 1 is saved for the fid we actually want793 cookie->nr_fids = 2; /* slot 1 is saved for the fid we actually want
784 * and slot 0 for the directory */794 * and slot 0 for the directory */
fs/afs/dynroot.c+1−1
@@ -278,7 +278,7 @@ static struct dentry *afs_lookup_atcell(struct inode *dir, struct dentry *dentry · 277 unmodified lines
278}278}
279 279
280/*280/*
281 * Transcribe the cell database into readdir content under the RCU read lock.281 * Transcribe the cell database into readdir content under net->cells_lock.
282 * Each cell produces two entries, one prefixed with a dot and one not.282 * Each cell produces two entries, one prefixed with a dot and one not.
283 */283 */
284static int afs_dynroot_readdir_cells(struct afs_net *net, struct dir_context *ctx)284static int afs_dynroot_readdir_cells(struct afs_net *net, struct dir_context *ctx)
fs/afs/fs_operation.c+1−1
@@ -348,7 +348,7 @@ int afs_put_operation(struct afs_operation *op) · 347 unmodified lines
348 for (i = 0; i < op->nr_files - 2; i++)348 for (i = 0; i < op->nr_files - 2; i++)
349 if (op->more_files[i].put_vnode)349 if (op->more_files[i].put_vnode)
350 iput(&op->more_files[i].vnode->netfs.inode);350 iput(&op->more_files[i].vnode->netfs.inode);
351 kfree(op->more_files);351 kvfree(op->more_files);
352 }352 }
353 353
354 if (op->estate) {354 if (op->estate) {
fs/afs/inode.c+7−8
@@ -52,9 +52,9 @@ static noinline void dump_vnode(struct afs_vnode *vnode, struct afs_vnode *paren · 51 unmodified lines
52/*52/*
53 * Set parameters for the netfs library53 * Set parameters for the netfs library
54 */54 */
55static void afs_set_netfs_context(struct afs_vnode *vnode)55static void afs_set_netfs_context(struct afs_vnode *vnode, bool is_file)
56{56{
57 netfs_inode_init(&vnode->netfs, &afs_req_ops, true);57 netfs_inode_init(&vnode->netfs, &afs_req_ops, is_file);
58}58}
59 59
60/*60/*
@@ -93,6 +93,10 @@ static int afs_inode_init_from_status(struct afs_operation *op, · 32 unmodified lines
93 inode->i_gid = make_kgid(&init_user_ns, status->group);93 inode->i_gid = make_kgid(&init_user_ns, status->group);
94 set_nlink(&vnode->netfs.inode, status->nlink);94 set_nlink(&vnode->netfs.inode, status->nlink);
95 95
96 i_size_write(inode, status->size);
97 inode_set_bytes(inode, status->size);
98 afs_set_netfs_context(vnode, status->type == AFS_FTYPE_FILE);
99
96 switch (status->type) {100 switch (status->type) {
97 case AFS_FTYPE_FILE:101 case AFS_FTYPE_FILE:
98 inode->i_mode = S_IFREG | (status->mode & S_IALLUGO);102 inode->i_mode = S_IFREG | (status->mode & S_IALLUGO);
@@ -126,7 +130,6 @@ static int afs_inode_init_from_status(struct afs_operation *op, · 27 unmodified lines
126 }130 }
127 inode->i_mapping->a_ops = &afs_symlink_aops;131 inode->i_mapping->a_ops = &afs_symlink_aops;
128 inode_nohighmem(inode);132 inode_nohighmem(inode);
129 mapping_set_release_always(inode->i_mapping);
130 break;133 break;
131 default:134 default:
132 dump_vnode(vnode, op->file[0].vnode != vnode ? op->file[0].vnode : NULL);135 dump_vnode(vnode, op->file[0].vnode != vnode ? op->file[0].vnode : NULL);
@@ -134,10 +137,6 @@ static int afs_inode_init_from_status(struct afs_operation *op, · 1 unmodified line
134 return afs_protocol_error(NULL, afs_eproto_file_type);137 return afs_protocol_error(NULL, afs_eproto_file_type);
135 }138 }
136 139
137 i_size_write(inode, status->size);
138 inode_set_bytes(inode, status->size);
139 afs_set_netfs_context(vnode);
140
141 vnode->invalid_before = status->data_version;140 vnode->invalid_before = status->data_version;
142 trace_afs_set_dv(vnode, status->data_version);141 trace_afs_set_dv(vnode, status->data_version);
143 inode_set_iversion_raw(&vnode->netfs.inode, status->data_version);142 inode_set_iversion_raw(&vnode->netfs.inode, status->data_version);
@@ -566,7 +565,6 @@ struct inode *afs_root_iget(struct super_block *sb, struct key *key) · 422 unmodified lines
566 565
567 vnode = AFS_FS_I(inode);566 vnode = AFS_FS_I(inode);
568 vnode->cb_v_check = atomic_read(&as->volume->cb_v_break);567 vnode->cb_v_check = atomic_read(&as->volume->cb_v_break);
569 afs_set_netfs_context(vnode);
570 568
571 op = afs_alloc_operation(key, as->volume);569 op = afs_alloc_operation(key, as->volume);
572 if (IS_ERR(op)) {570 if (IS_ERR(op)) {
@@ -682,6 +680,7 @@ void afs_evict_inode(struct inode *inode) · 109 unmodified lines
682 inode->i_mapping->a_ops->writepages(inode->i_mapping, &wbc);680 inode->i_mapping->a_ops->writepages(inode->i_mapping, &wbc);
683 }681 }
684 682
683 flush_delayed_work(&vnode->lock_work);
685 netfs_wait_for_outstanding_io(inode);684 netfs_wait_for_outstanding_io(inode);
686 truncate_inode_pages_final(&inode->i_data);685 truncate_inode_pages_final(&inode->i_data);
687 netfs_free_folioq_buffer(vnode->directory);686 netfs_free_folioq_buffer(vnode->directory);
fs/afs/internal.h+1−2
@@ -388,6 +388,7 @@ struct afs_cell { · 387 unmodified lines
388#define AFS_CELL_FL_NO_GC 0 /* The cell was added manually, don't auto-gc */388#define AFS_CELL_FL_NO_GC 0 /* The cell was added manually, don't auto-gc */
389#define AFS_CELL_FL_DO_LOOKUP 1 /* DNS lookup requested */389#define AFS_CELL_FL_DO_LOOKUP 1 /* DNS lookup requested */
390#define AFS_CELL_FL_CHECK_ALIAS 2 /* Need to check for aliases */390#define AFS_CELL_FL_CHECK_ALIAS 2 /* Need to check for aliases */
391#define AFS_CELL_FL_HAVE_INO 3 /* Have dynroot_ino */
391 enum afs_cell_state state;392 enum afs_cell_state state;
392 short error;393 short error;
393 enum dns_record_source dns_source:8; /* Latest source of data from lookup */394 enum dns_record_source dns_source:8; /* Latest source of data from lookup */
@@ -750,8 +751,6 @@ static inline void afs_vnode_set_cache(struct afs_vnode *vnode, · 356 unmodified lines
750{751{
751#ifdef CONFIG_AFS_FSCACHE752#ifdef CONFIG_AFS_FSCACHE
752 vnode->netfs.cache = cookie;753 vnode->netfs.cache = cookie;
753 if (cookie)
754 mapping_set_release_always(vnode->netfs.inode.i_mapping);
755#endif754#endif
756}755}
757 756
fs/afs/super.c+3−2
@@ -587,7 +587,8 @@ static int afs_get_tree(struct fs_context *fc) · 586 unmodified lines
587 }587 }
588 588
589 fc->root = dget(sb->s_root);589 fc->root = dget(sb->s_root);
590 trace_afs_get_tree(as->cell, as->volume);590 if (!ctx->dyn_root)
591 trace_afs_get_tree(as->cell, as->volume);
591 _leave(" = 0 [%p]", sb);592 _leave(" = 0 [%p]", sb);
592 return 0;593 return 0;
593 594
@@ -659,7 +660,6 @@ static void afs_i_init_once(void *_vnode) · 65 unmodified lines
659 INIT_LIST_HEAD(&vnode->wb_keys);660 INIT_LIST_HEAD(&vnode->wb_keys);
660 INIT_LIST_HEAD(&vnode->pending_locks);661 INIT_LIST_HEAD(&vnode->pending_locks);
661 INIT_LIST_HEAD(&vnode->granted_locks);662 INIT_LIST_HEAD(&vnode->granted_locks);
662 INIT_DELAYED_WORK(&vnode->lock_work, afs_lock_work);
663 INIT_LIST_HEAD(&vnode->cb_mmap_link);663 INIT_LIST_HEAD(&vnode->cb_mmap_link);
664 seqlock_init(&vnode->cb_lock);664 seqlock_init(&vnode->cb_lock);
665}665}
@@ -693,6 +693,7 @@ static struct inode *afs_alloc_inode(struct super_block *sb) · 27 unmodified lines
693 693
694 init_rwsem(&vnode->rmdir_lock);694 init_rwsem(&vnode->rmdir_lock);
695 INIT_WORK(&vnode->cb_work, afs_invalidate_mmap_work);695 INIT_WORK(&vnode->cb_work, afs_invalidate_mmap_work);
696 INIT_DELAYED_WORK(&vnode->lock_work, afs_lock_work);
696 697
697 _leave(" = %p", &vnode->netfs.inode);698 _leave(" = %p", &vnode->netfs.inode);
698 return &vnode->netfs.inode;699 return &vnode->netfs.inode;
fs/afs/symlink.c+2−2
@@ -255,11 +255,11 @@ int afs_symlink_writepages(struct address_space *mapping, · 254 unmodified lines
255 }255 }
256 256
257 if (ret == 0) {257 if (ret == 0) {
258 mutex_lock(&vnode->netfs.wb_lock);258 netfs_wb_begin(&vnode->netfs, false);
259 netfs_free_folioq_buffer(vnode->directory);259 netfs_free_folioq_buffer(vnode->directory);
260 vnode->directory = NULL;260 vnode->directory = NULL;
261 vnode->directory_size = 0;261 vnode->directory_size = 0;
262 mutex_unlock(&vnode->netfs.wb_lock);262 netfs_wb_end(&vnode->netfs);
263 } else if (ret == 1) {263 } else if (ret == 1) {
264 ret = 0; /* Skipped write due to lock conflict. */264 ret = 0; /* Skipped write due to lock conflict. */
265 }265 }
fs/afs/vl_list.c+21−3
@@ -92,7 +92,7 @@ static struct afs_addr_list *afs_extract_vl_addrs(struct afs_net *net, · 91 unmodified lines
92{92{
93 struct afs_addr_list *alist;93 struct afs_addr_list *alist;
94 const u8 *b = *_b;94 const u8 *b = *_b;
95 int ret = -EINVAL;95 int ret;
96 96
97 alist = afs_alloc_addrlist(nr_addrs);97 alist = afs_alloc_addrlist(nr_addrs);
98 if (!alist)98 if (!alist)
@@ -110,6 +110,7 @@ static struct afs_addr_list *afs_extract_vl_addrs(struct afs_net *net, · 11 unmodified lines
110 case DNS_ADDRESS_IS_IPV4:110 case DNS_ADDRESS_IS_IPV4:
111 if (end - b < 4) {111 if (end - b < 4) {
112 _leave(" = -EINVAL [short inet]");112 _leave(" = -EINVAL [short inet]");
113 ret = -EINVAL;
113 goto error;114 goto error;
114 }115 }
115 memcpy(x, b, 4);116 memcpy(x, b, 4);
@@ -122,6 +123,7 @@ static struct afs_addr_list *afs_extract_vl_addrs(struct afs_net *net, · 6 unmodified lines
122 case DNS_ADDRESS_IS_IPV6:123 case DNS_ADDRESS_IS_IPV6:
123 if (end - b < 16) {124 if (end - b < 16) {
124 _leave(" = -EINVAL [short inet6]");125 _leave(" = -EINVAL [short inet6]");
126 ret = -EINVAL;
125 goto error;127 goto error;
126 }128 }
127 memcpy(x, b, 16);129 memcpy(x, b, 16);
@@ -198,6 +200,8 @@ struct afs_vlserver_list *afs_extract_vlserver_list(struct afs_cell *cell, · 70 unmodified lines
198 200
199 b += sizeof(*hdr);201 b += sizeof(*hdr);
200 while (end - b >= sizeof(bs)) {202 while (end - b >= sizeof(bs)) {
203 int nlen;
204
201 bs.name_len = afs_extract_le16(&b);205 bs.name_len = afs_extract_le16(&b);
202 bs.priority = afs_extract_le16(&b);206 bs.priority = afs_extract_le16(&b);
203 bs.weight = afs_extract_le16(&b);207 bs.weight = afs_extract_le16(&b);
@@ -207,10 +211,12 @@ struct afs_vlserver_list *afs_extract_vlserver_list(struct afs_cell *cell, · 3 unmodified lines
207 bs.protocol = *b++;211 bs.protocol = *b++;
208 bs.nr_addrs = *b++;212 bs.nr_addrs = *b++;
209 213
214 nlen = min3(bs.name_len, end - b, 255);
215
210 _debug("extract %u %u %u %u %u %u %*.*s",216 _debug("extract %u %u %u %u %u %u %*.*s",
211 bs.name_len, bs.priority, bs.weight,217 bs.name_len, bs.priority, bs.weight,
212 bs.port, bs.protocol, bs.nr_addrs,218 bs.port, bs.protocol, bs.nr_addrs,
213 bs.name_len, bs.name_len, b);219 bs.name_len, nlen, b);
214 220
215 if (end - b < bs.name_len)221 if (end - b < bs.name_len)
216 break;222 break;
@@ -287,8 +293,20 @@ struct afs_vlserver_list *afs_extract_vlserver_list(struct afs_cell *cell, · 70 unmodified lines
287 afs_put_addrlist(old, afs_alist_trace_put_vlserver_old);293 afs_put_addrlist(old, afs_alist_trace_put_vlserver_old);
288 }294 }
289 295
296 /* Check for duplicates in the server list */
297 for (j = 0; j < vllist->nr_servers; j++) {
298 struct afs_vlserver *s = vllist->servers[j].server;
290 299
291 /* TODO: Might want to check for duplicates */300 if (s->name_len == server->name_len &&
301 s->port == server->port &&
302 strncasecmp(s->name, server->name, server->name_len) == 0) {
303 afs_put_vlserver(cell->net, server);
304 server = NULL;
305 break;
306 }
307 }
308 if (!server)
309 continue;
292 310
293 /* Insertion-sort by priority and weight */311 /* Insertion-sort by priority and weight */
294 for (j = 0; j < vllist->nr_servers; j++) {312 for (j = 0; j < vllist->nr_servers; j++) {
fs/afs/volume.c+1−1
@@ -40,7 +40,7 @@ static struct afs_volume *afs_insert_volume_into_cell(struct afs_cell *cell, · 39 unmodified lines
40 goto found;40 goto found;
41 }41 }
42 42
43 set_bit(AFS_VOLUME_RM_TREE, &volume->flags);43 set_bit(AFS_VOLUME_RM_TREE, &p->flags);
44 rb_replace_node_rcu(&p->cell_node, &volume->cell_node, &cell->volumes);44 rb_replace_node_rcu(&p->cell_node, &volume->cell_node, &cell->volumes);
45 }45 }
46 }46 }
fs/bpf_fs_kfuncs.c+14−9
@@ -360,18 +360,23 @@ __bpf_kfunc int bpf_cgroup_read_xattr(struct cgroup *cgroup, const char *name__s · 359 unmodified lines
360#endif /* CONFIG_CGROUPS */360#endif /* CONFIG_CGROUPS */
361 361
362/**362/**
363 * bpf_real_inode - get the real inode backing a dentry363 * bpf_real_data_inode - get the real inode hosting a file's data
364 * @dentry: dentry to resolve364 * @file: file to resolve
365 *365 *
366 * If the dentry is on a union/overlay filesystem, return the underlying, real366 * Resolve @file to the inode that hosts its data. For a regular file on a
367 * inode that hosts the data. Otherwise return the inode attached to the367 * union/overlay filesystem this is the underlying (upper or lower) inode that
368 * dentry itself.368 * stores the data, not the overlay inode.
369 *369 *
370 * Return: The real inode backing the dentry, or NULL for a negative dentry.370 * Data resolution only applies to regular files. For a non-regular file (e.g.
371 * a device node, fifo or socket) on a union/overlay filesystem the overlay
372 * inode itself is returned; for any file on a non-union filesystem the inode
373 * attached to @file is returned.
374 *
375 * Return: The inode hosting @file's data, or NULL.
371 */376 */
372__bpf_kfunc struct inode *bpf_real_inode(struct dentry *dentry)377__bpf_kfunc struct inode *bpf_real_data_inode(struct file *file)
373{378{
374 return d_real_inode(dentry);379 return d_real_inode(file_dentry(file));
375}380}
376 381
377__bpf_kfunc_end_defs();382__bpf_kfunc_end_defs();
@@ -384,7 +389,7 @@ BTF_ID_FLAGS(func, bpf_get_dentry_xattr, KF_SLEEPABLE) · 6 unmodified lines
384BTF_ID_FLAGS(func, bpf_get_file_xattr, KF_SLEEPABLE)389BTF_ID_FLAGS(func, bpf_get_file_xattr, KF_SLEEPABLE)
385BTF_ID_FLAGS(func, bpf_set_dentry_xattr, KF_SLEEPABLE)390BTF_ID_FLAGS(func, bpf_set_dentry_xattr, KF_SLEEPABLE)
386BTF_ID_FLAGS(func, bpf_remove_dentry_xattr, KF_SLEEPABLE)391BTF_ID_FLAGS(func, bpf_remove_dentry_xattr, KF_SLEEPABLE)
387BTF_ID_FLAGS(func, bpf_real_inode, KF_SLEEPABLE | KF_RET_NULL)392BTF_ID_FLAGS(func, bpf_real_data_inode, KF_SLEEPABLE | KF_RET_NULL)
388BTF_KFUNCS_END(bpf_fs_kfunc_set_ids)393BTF_KFUNCS_END(bpf_fs_kfunc_set_ids)
389 394
390static int bpf_fs_kfuncs_filter(const struct bpf_prog *prog, u32 kfunc_id)395static int bpf_fs_kfuncs_filter(const struct bpf_prog *prog, u32 kfunc_id)
fs/cachefiles/namei.c+1−3
@@ -209,7 +209,6 @@ lookup_error: · 208 unmodified lines
209 return ERR_PTR(ret);209 return ERR_PTR(ret);
210 210
211nomem_d_alloc:211nomem_d_alloc:
212 inode_unlock(d_inode(dir));
213 _leave(" = -ENOMEM");212 _leave(" = -ENOMEM");
214 return ERR_PTR(-ENOMEM);213 return ERR_PTR(-ENOMEM);
215}214}
@@ -375,7 +374,7 @@ try_again: · 159 unmodified lines
375 "Rename failed with error %d", ret);374 "Rename failed with error %d", ret);
376 }375 }
377 376
378 __cachefiles_unmark_inode_in_use(object, d_inode(rep));377 cachefiles_do_unmark_inode_in_use(object, d_inode(rep));
379 end_renaming(&rd);378 end_renaming(&rd);
380 _leave(" = 0");379 _leave(" = 0");
381 return 0;380 return 0;
@@ -467,7 +466,6 @@ struct file *cachefiles_create_tmpfile(struct cachefiles_object *object) · 85 unmodified lines
467 ret = -EINVAL;466 ret = -EINVAL;
468 if (unlikely(!file->f_op->read_iter) ||467 if (unlikely(!file->f_op->read_iter) ||
469 unlikely(!file->f_op->write_iter)) {468 unlikely(!file->f_op->write_iter)) {
470 fput(file);
471 pr_notice("Cache does not support read_iter and write_iter\n");469 pr_notice("Cache does not support read_iter and write_iter\n");
472 goto err_unuse;470 goto err_unuse;
473 }471 }
fs/exec.c+1−1
@@ -1717,7 +1717,7 @@ static int exec_binprm(struct linux_binprm *bprm) · 1716 unmodified lines
1717 old_vpid = task_pid_nr_ns(current, task_active_pid_ns(current->parent));1717 old_vpid = task_pid_nr_ns(current, task_active_pid_ns(current->parent));
1718 rcu_read_unlock();1718 rcu_read_unlock();
1719 1719
1720 /* This allows 4 levels of binfmt rewrites before failing hard. */1720 /* This allows 5 levels of binfmt rewrites before failing hard. */
1721 for (depth = 0;; depth++) {1721 for (depth = 0;; depth++) {
1722 struct file *exec;1722 struct file *exec;
1723 if (depth > 5)1723 if (depth > 5)
fs/exfat/iomap.c+1−4
@@ -253,10 +253,7 @@ static void exfat_iomap_read_end_io(struct bio *bio) · 252 unmodified lines
253static void exfat_iomap_bio_submit_read(const struct iomap_iter *iter,253static void exfat_iomap_bio_submit_read(const struct iomap_iter *iter,
254 struct iomap_read_folio_ctx *ctx)254 struct iomap_read_folio_ctx *ctx)
255{255{
256 struct bio *bio = ctx->read_ctx;256 iomap_bio_submit_read_endio(iter, ctx, exfat_iomap_read_end_io);
257
258 bio->bi_end_io = exfat_iomap_read_end_io;
259 submit_bio(bio);
260}257}
261 258
262const struct iomap_read_ops exfat_iomap_bio_read_ops = {259const struct iomap_read_ops exfat_iomap_bio_read_ops = {
fs/fat/dir.c+40−4
@@ -130,6 +130,31 @@ static inline int fat_get_entry(struct inode *dir, loff_t *pos, · 129 unmodified lines
130 return fat__get_entry(dir, pos, bh, de);130 return fat__get_entry(dir, pos, bh, de);
131}131}
132 132
133/*
134 * Like fat_get_entry(), but honour the FAT end-of-directory marker:
135 * a dirent whose first name byte is NUL terminates iteration per the
136 * spec, which also guarantees that every following slot is zeroed.
137 * Skip straight to the end of the directory so the next call returns
138 * -1 from fat_bmap() without re-reading the trailing zero slots, and
139 * so callers that persist *pos across invocations (e.g. readdir's
140 * ctx->pos) keep reporting EOD. Release *bh and set it to NULL to
141 * match fat_get_entry()'s contract that *bh is NULL on the -1 return.
142 */
143static int fat_get_entry_eod(struct inode *dir, loff_t *pos,
144 struct buffer_head **bh,
145 struct msdos_dir_entry **de)
146{
147 int err = fat_get_entry(dir, pos, bh, de);
148
149 if (err == 0 && (*de)->name[0] == 0) {
150 brelse(*bh);
151 *bh = NULL;
152 *pos = dir->i_size;
153 return -1;
154 }
155 return err;
156}
157
133/*158/*
134 * Convert Unicode 16 to UTF-8, translated Unicode, or ASCII.159 * Convert Unicode 16 to UTF-8, translated Unicode, or ASCII.
135 * If uni_xlate is enabled and we can't get a 1:1 conversion, use a160 * If uni_xlate is enabled and we can't get a 1:1 conversion, use a
@@ -327,7 +352,7 @@ parse_long: · 191 unmodified lines
327 352
328 if (ds->id & 0x40)353 if (ds->id & 0x40)
329 (*unicode)[offset + 13] = 0;354 (*unicode)[offset + 13] = 0;
330 if (fat_get_entry(dir, pos, bh, de) < 0)355 if (fat_get_entry_eod(dir, pos, bh, de) < 0)
331 return PARSE_EOF;356 return PARSE_EOF;
332 if (slot == 0)357 if (slot == 0)
333 break;358 break;
@@ -489,7 +514,7 @@ int fat_search_long(struct inode *inode, const unsigned char *name, · 155 unmodified lines
489 514
490 err = -ENOENT;515 err = -ENOENT;
491 while (1) {516 while (1) {
492 if (fat_get_entry(inode, &cpos, &bh, &de) == -1)517 if (fat_get_entry_eod(inode, &cpos, &bh, &de) == -1)
493 goto end_of_dir;518 goto end_of_dir;
494parse_record:519parse_record:
495 nr_slots = 0;520 nr_slots = 0;
@@ -601,7 +626,7 @@ static int __fat_readdir(struct inode *inode, struct file *file, · 105 unmodified lines
601 626
602 bh = NULL;627 bh = NULL;
603get_new:628get_new:
604 if (fat_get_entry(inode, &cpos, &bh, &de) == -1)629 if (fat_get_entry_eod(inode, &cpos, &bh, &de) == -1)
605 goto end_of_dir;630 goto end_of_dir;
606parse_record:631parse_record:
607 nr_slots = 0;632 nr_slots = 0;
@@ -885,7 +910,7 @@ static int fat_get_short_entry(struct inode *dir, loff_t *pos, · 277 unmodified lines
885 struct buffer_head **bh,910 struct buffer_head **bh,
886 struct msdos_dir_entry **de)911 struct msdos_dir_entry **de)
887{912{
888 while (fat_get_entry(dir, pos, bh, de) >= 0) {913 while (fat_get_entry_eod(dir, pos, bh, de) >= 0) {
889 /* free entry or long name entry or volume label */914 /* free entry or long name entry or volume label */
890 if (!IS_FREE((*de)->name) && !((*de)->attr & ATTR_VOLUME))915 if (!IS_FREE((*de)->name) && !((*de)->attr & ATTR_VOLUME))
891 return 0;916 return 0;
@@ -1302,6 +1327,7 @@ int fat_add_entries(struct inode *dir, void *slots, int nr_slots, · 410 unmodified lines
1302 struct msdos_dir_entry *de;1327 struct msdos_dir_entry *de;
1303 int err, free_slots, i, nr_bhs;1328 int err, free_slots, i, nr_bhs;
1304 loff_t pos;1329 loff_t pos;
1330 bool saw_eod;
1305 1331
1306 sinfo->nr_slots = nr_slots;1332 sinfo->nr_slots = nr_slots;
1307 1333
@@ -1310,12 +1336,15 @@ int fat_add_entries(struct inode *dir, void *slots, int nr_slots, · 2 unmodified lines
1310 bh = prev = NULL;1336 bh = prev = NULL;
1311 pos = 0;1337 pos = 0;
1312 err = -ENOSPC;1338 err = -ENOSPC;
1339 saw_eod = false;
1313 while (fat_get_entry(dir, &pos, &bh, &de) > -1) {1340 while (fat_get_entry(dir, &pos, &bh, &de) > -1) {
1314 /* check the maximum size of directory */1341 /* check the maximum size of directory */
1315 if (pos >= FAT_MAX_DIR_SIZE)1342 if (pos >= FAT_MAX_DIR_SIZE)
1316 goto error;1343 goto error;
1317 1344
1318 if (IS_FREE(de->name)) {1345 if (IS_FREE(de->name)) {
1346 if (de->name[0] == 0)
1347 saw_eod = true;
1319 if (prev != bh) {1348 if (prev != bh) {
1320 get_bh(bh);1349 get_bh(bh);
1321 bhs[nr_bhs] = prev = bh;1350 bhs[nr_bhs] = prev = bh;
@@ -1325,6 +1354,13 @@ int fat_add_entries(struct inode *dir, void *slots, int nr_slots, · 3 unmodified lines
1325 if (free_slots == nr_slots)1354 if (free_slots == nr_slots)
1326 goto found;1355 goto found;
1327 } else {1356 } else {
1357 if (saw_eod) {
1358 fat_fs_error_ratelimit(sb,
1359 "allocated dir entry found after end-of-directory marker (i_pos %lld)",
1360 MSDOS_I(dir)->i_pos);
1361 err = -EIO;
1362 goto error;
1363 }
1328 for (i = 0; i < nr_bhs; i++)1364 for (i = 0; i < nr_bhs; i++)
1329 brelse(bhs[i]);1365 brelse(bhs[i]);
1330 prev = NULL;1366 prev = NULL;
fs/fhandle.c+1−1
@@ -295,7 +295,7 @@ static bool capable_wrt_mount(struct mount *mount) · 294 unmodified lines
295 */295 */
296 guard(rcu)();296 guard(rcu)();
297 mnt_ns = READ_ONCE(mount->mnt_ns);297 mnt_ns = READ_ONCE(mount->mnt_ns);
298 return ns_capable(mnt_ns->user_ns, CAP_SYS_ADMIN);298 return mnt_ns && ns_capable(mnt_ns->user_ns, CAP_SYS_ADMIN);
299}299}
300 300
301static inline int may_decode_fh(struct handle_to_path_ctx *ctx,301static inline int may_decode_fh(struct handle_to_path_ctx *ctx,
fs/freevxfs/vxfs_bmap.c+2−1
@@ -227,7 +227,8 @@ vxfs_bmap_typed(struct inode *ip, long iblock) · 226 unmodified lines
227 return 0;227 return 0;
228 }228 }
229 default:229 default:
230 BUG();230 WARN_ON_ONCE(1);
231 return 0;
231 }232 }
232 }233 }
233 234
fs/fuse/file.c+3−11
@@ -981,19 +981,8 @@ static int fuse_iomap_read_folio_range_async(const struct iomap_iter *iter, · 980 unmodified lines
981 return ret;981 return ret;
982}982}
983 983
984static void fuse_iomap_submit_read(const struct iomap_iter *iter,
985 struct iomap_read_folio_ctx *ctx)
986{
987 struct fuse_fill_read_data *data = ctx->read_ctx;
988
989 if (data->ia)
990 fuse_send_readpages(data->ia, data->file, data->nr_bytes,
991 data->fc->async_read);
992}
993
994static const struct iomap_read_ops fuse_iomap_read_ops = {984static const struct iomap_read_ops fuse_iomap_read_ops = {
995 .read_folio_range = fuse_iomap_read_folio_range_async,985 .read_folio_range = fuse_iomap_read_folio_range_async,
996 .submit_read = fuse_iomap_submit_read,
997};986};
998 987
999static int fuse_read_folio(struct file *file, struct folio *folio)988static int fuse_read_folio(struct file *file, struct folio *folio)
@@ -1116,6 +1105,9 @@ static void fuse_readahead(struct readahead_control *rac) · 116 unmodified lines
1116 return;1105 return;
1117 1106
1118 iomap_readahead(&fuse_iomap_ops, &ctx, NULL);1107 iomap_readahead(&fuse_iomap_ops, &ctx, NULL);
1108 if (data.ia)
1109 fuse_send_readpages(data.ia, data.file, data.nr_bytes,
1110 fc->async_read);
1119}1111}
1120 1112
1121static ssize_t fuse_cache_read_iter(struct kiocb *iocb, struct iov_iter *to)1113static ssize_t fuse_cache_read_iter(struct kiocb *iocb, struct iov_iter *to)
fs/iomap/bio.c+12−3
@@ -78,14 +78,24 @@ u32 iomap_finish_ioend_buffered_read(struct iomap_ioend *ioend) · 77 unmodified lines
78 return __iomap_read_end_io(&ioend->io_bio, ioend->io_error);78 return __iomap_read_end_io(&ioend->io_bio, ioend->io_error);
79}79}
80 80
81static void iomap_bio_submit_read(const struct iomap_iter *iter,81void iomap_bio_submit_read_endio(const struct iomap_iter *iter,
82 struct iomap_read_folio_ctx *ctx)82 struct iomap_read_folio_ctx *ctx, bio_end_io_t end_io)
83{83{
84 struct bio *bio = ctx->read_ctx;84 struct bio *bio = ctx->read_ctx;
85 85
86 bio->bi_end_io = end_io;
86 if (iter->iomap.flags & IOMAP_F_INTEGRITY)87 if (iter->iomap.flags & IOMAP_F_INTEGRITY)
87 fs_bio_integrity_alloc(bio);88 fs_bio_integrity_alloc(bio);
88 submit_bio(bio);89 submit_bio(bio);
90
91 ctx->read_ctx = NULL;
92}
93EXPORT_SYMBOL_GPL(iomap_bio_submit_read_endio);
94
95static void iomap_bio_submit_read(const struct iomap_iter *iter,
96 struct iomap_read_folio_ctx *ctx)
97{
98 return iomap_bio_submit_read_endio(iter, ctx, iomap_read_end_io);
89}99}
90 100
91static struct bio_set *iomap_read_bio_set(struct iomap_read_folio_ctx *ctx)101static struct bio_set *iomap_read_bio_set(struct iomap_read_folio_ctx *ctx)
@@ -127,7 +137,6 @@ static void iomap_read_alloc_bio(const struct iomap_iter *iter, · 35 unmodified lines
127 if (ctx->rac)137 if (ctx->rac)
128 bio->bi_opf |= REQ_RAHEAD;138 bio->bi_opf |= REQ_RAHEAD;
129 bio->bi_iter.bi_sector = iomap_sector(iomap, iter->pos);139 bio->bi_iter.bi_sector = iomap_sector(iomap, iter->pos);
130 bio->bi_end_io = iomap_read_end_io;
131 bio_add_folio_nofail(bio, folio, plen,140 bio_add_folio_nofail(bio, folio, plen,
132 offset_in_folio(folio, iter->pos));141 offset_in_folio(folio, iter->pos));
133 ctx->read_ctx = bio;142 ctx->read_ctx = bio;
fs/iomap/buffered-io.c+8−8
@@ -642,12 +642,12 @@ void iomap_read_folio(const struct iomap_ops *ops, · 641 unmodified lines
642 fsverity_readahead(ctx->vi, folio->index,642 fsverity_readahead(ctx->vi, folio->index,
643 folio_nr_pages(folio));643 folio_nr_pages(folio));
644 644
645 while ((ret = iomap_iter(&iter, ops)) > 0)645 while ((ret = iomap_iter(&iter, ops)) > 0) {
646 iter.status = iomap_read_folio_iter(&iter, ctx,646 iter.status = iomap_read_folio_iter(&iter, ctx,
647 &bytes_submitted);647 &bytes_submitted);
648 648 if (ctx->read_ctx && ctx->ops->submit_read)
649 if (ctx->read_ctx && ctx->ops->submit_read)649 ctx->ops->submit_read(&iter, ctx);
650 ctx->ops->submit_read(&iter, ctx);650 }
651 651
652 if (ctx->cur_folio)652 if (ctx->cur_folio)
653 iomap_read_end(ctx->cur_folio, bytes_submitted);653 iomap_read_end(ctx->cur_folio, bytes_submitted);
@@ -718,12 +718,12 @@ void iomap_readahead(const struct iomap_ops *ops, · 64 unmodified lines
718 fsverity_readahead(ctx->vi, readahead_index(rac),718 fsverity_readahead(ctx->vi, readahead_index(rac),
719 readahead_count(rac));719 readahead_count(rac));
720 720
721 while (iomap_iter(&iter, ops) > 0)721 while (iomap_iter(&iter, ops) > 0) {
722 iter.status = iomap_readahead_iter(&iter, ctx,722 iter.status = iomap_readahead_iter(&iter, ctx,
723 &cur_bytes_submitted);723 &cur_bytes_submitted);
724 724 if (ctx->read_ctx && ctx->ops->submit_read)
725 if (ctx->read_ctx && ctx->ops->submit_read)725 ctx->ops->submit_read(&iter, ctx);
726 ctx->ops->submit_read(&iter, ctx);726 }
727 727
728 if (ctx->cur_folio)728 if (ctx->cur_folio)
729 iomap_read_end(ctx->cur_folio, cur_bytes_submitted);729 iomap_read_end(ctx->cur_folio, cur_bytes_submitted);
fs/iomap/direct-io.c+6−1
@@ -369,7 +369,7 @@ static ssize_t iomap_dio_bio_iter_one(struct iomap_iter *iter, · 368 unmodified lines
369 */369 */
370 if ((op & REQ_ATOMIC) && WARN_ON_ONCE(ret != iomap_length(iter))) {370 if ((op & REQ_ATOMIC) && WARN_ON_ONCE(ret != iomap_length(iter))) {
371 ret = -EINVAL;371 ret = -EINVAL;
372 goto out_put_bio;372 goto out_bio_release_pages;
373 }373 }
374 374
375 if (iter->iomap.flags & IOMAP_F_INTEGRITY) {375 if (iter->iomap.flags & IOMAP_F_INTEGRITY) {
@@ -393,6 +393,11 @@ static ssize_t iomap_dio_bio_iter_one(struct iomap_iter *iter, · 17 unmodified lines
393 iomap_dio_submit_bio(iter, dio, bio, pos);393 iomap_dio_submit_bio(iter, dio, bio, pos);
394 return ret;394 return ret;
395 395
396out_bio_release_pages:
397 if (dio->flags & IOMAP_DIO_BOUNCE)
398 bio_iov_iter_unbounce(bio, true, false);
399 else
400 bio_release_pages(bio, false);
396out_put_bio:401out_put_bio:
397 bio_put(bio);402 bio_put(bio);
398 return ret;403 return ret;
fs/iomap/ioend.c+6−2
@@ -298,8 +298,12 @@ new_ioend: · 297 unmodified lines
298 * appending writes.298 * appending writes.
299 */299 */
300 ioend->io_size += map_len;300 ioend->io_size += map_len;
301 if (ioend->io_offset + ioend->io_size > end_pos)301 if (ioend->io_offset + ioend->io_size > end_pos) {
302 ioend->io_size = end_pos - ioend->io_offset;302 if (ioend->io_offset >= end_pos)
303 ioend->io_size = 0;
304 else
305 ioend->io_size = end_pos - ioend->io_offset;
306 }
303 307
304 wbc_account_cgroup_owner(wpc->wbc, folio, map_len);308 wbc_account_cgroup_owner(wpc->wbc, folio, map_len);
305 return map_len;309 return map_len;
fs/minix/minix.h+1−1
@@ -97,7 +97,7 @@ static inline struct minix_inode_info *minix_i(struct inode *inode) · 96 unmodified lines
97 97
98static inline unsigned minix_blocks_needed(unsigned bits, unsigned blocksize)98static inline unsigned minix_blocks_needed(unsigned bits, unsigned blocksize)
99{99{
100 return DIV_ROUND_UP(bits, blocksize * 8);100 return DIV_ROUND_UP_POW2(bits, blocksize * 8);
101}101}
102 102
103#if defined(CONFIG_MINIX_FS_NATIVE_ENDIAN) && \103#if defined(CONFIG_MINIX_FS_NATIVE_ENDIAN) && \
fs/namei.c+4−0
@@ -4736,6 +4736,10 @@ int vfs_tmpfile(struct mnt_idmap *idmap, · 4735 unmodified lines
4736 int error;4736 int error;
4737 int open_flag = file->f_flags;4737 int open_flag = file->f_flags;
4738 4738
4739 /* A tmpfile is I_LINKABLE, so guard its owner like may_o_create(). */
4740 if (!fsuidgid_has_mapping(dir->i_sb, idmap))
4741 return -EOVERFLOW;
4742
4739 /* we want directory to be writable */4743 /* we want directory to be writable */
4740 error = inode_permission(idmap, dir, MAY_WRITE | MAY_EXEC);4744 error = inode_permission(idmap, dir, MAY_WRITE | MAY_EXEC);
4741 if (error)4745 if (error)
fs/netfs/buffered_read.c+1−1
@@ -659,7 +659,7 @@ retry: · 658 unmodified lines
659 * within the cache granule containing the EOF, in which case we need659 * within the cache granule containing the EOF, in which case we need
660 * to preload the granule.660 * to preload the granule.
661 */661 */
662 if (!netfs_is_cache_enabled(ctx) &&662 if (!netfs_is_cache_maybe_enabled(ctx) &&
663 netfs_skip_folio_read(folio, pos, len, false)) {663 netfs_skip_folio_read(folio, pos, len, false)) {
664 netfs_stat(&netfs_n_rh_write_zskip);664 netfs_stat(&netfs_n_rh_write_zskip);
665 goto have_folio_no_wait;665 goto have_folio_no_wait;
fs/netfs/buffered_write.c+1−1
@@ -277,7 +277,7 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter, · 276 unmodified lines
277 * caching service temporarily because the backing store got277 * caching service temporarily because the backing store got
278 * culled.278 * culled.
279 */279 */
280 if (netfs_is_cache_enabled(ctx)) {280 if (netfs_is_cache_maybe_enabled(ctx)) {
281 if (finfo) {281 if (finfo) {
282 netfs_stat(&netfs_n_wh_wstream_conflict);282 netfs_stat(&netfs_n_wh_wstream_conflict);
283 goto flush_content;283 goto flush_content;
fs/netfs/direct_write.c+7−11
@@ -166,13 +166,16 @@ static int netfs_unbuffered_write(struct netfs_io_request *wreq) · 165 unmodified lines
166 */166 */
167 subreq->error = -EAGAIN;167 subreq->error = -EAGAIN;
168 trace_netfs_sreq(subreq, netfs_sreq_trace_retry);168 trace_netfs_sreq(subreq, netfs_sreq_trace_retry);
169 if (subreq->transferred > 0)169 if (subreq->transferred > 0) {
170 iov_iter_advance(&wreq->buffer.iter, subreq->transferred);170 iov_iter_advance(&wreq->buffer.iter, subreq->transferred);
171 wreq->transferred += subreq->transferred;
172 }
171 173
172 if (stream->source == NETFS_UPLOAD_TO_SERVER &&174 if (stream->source == NETFS_UPLOAD_TO_SERVER &&
173 wreq->netfs_ops->retry_request)175 wreq->netfs_ops->retry_request)
174 wreq->netfs_ops->retry_request(wreq, stream);176 wreq->netfs_ops->retry_request(wreq, stream);
175 177
178 __clear_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags);
176 __clear_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags);179 __clear_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags);
177 __clear_bit(NETFS_SREQ_BOUNDARY, &subreq->flags);180 __clear_bit(NETFS_SREQ_BOUNDARY, &subreq->flags);
178 __clear_bit(NETFS_SREQ_FAILED, &subreq->flags);181 __clear_bit(NETFS_SREQ_FAILED, &subreq->flags);
@@ -186,17 +189,10 @@ static int netfs_unbuffered_write(struct netfs_io_request *wreq) · 7 unmodified lines
186 189
187 netfs_get_subrequest(subreq, netfs_sreq_trace_get_resubmit);190 netfs_get_subrequest(subreq, netfs_sreq_trace_get_resubmit);
188 191
189 if (stream->prepare_write) {192 if (stream->prepare_write)
190 stream->prepare_write(subreq);193 stream->prepare_write(subreq);
191 __set_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags);194 __set_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags);
192 netfs_stat(&netfs_n_wh_retry_write_subreq);195 netfs_stat(&netfs_n_wh_retry_write_subreq);
193 } else {
194 struct iov_iter source;
195
196 netfs_reset_iter(subreq);
197 source = subreq->io_iter;
198 netfs_reissue_write(stream, subreq, &source);
199 }
200 }196 }
201 197
202 netfs_unbuffered_write_done(wreq);198 netfs_unbuffered_write_done(wreq);
fs/netfs/internal.h+12−0
@@ -239,6 +239,18 @@ static inline bool netfs_is_cache_enabled(struct netfs_inode *ctx) · 238 unmodified lines
239#endif239#endif
240}240}
241 241
242static inline bool netfs_is_cache_maybe_enabled(struct netfs_inode *ctx)
243{
244#if IS_ENABLED(CONFIG_FSCACHE)
245 struct fscache_cookie *cookie = ctx->cache;
246
247 return fscache_cookie_valid(cookie) &&
248 test_bit(FSCACHE_COOKIE_IS_CACHING, &cookie->flags);
249#else
250 return false;
251#endif
252}
253
242/*254/*
243 * Get a ref on a netfs group attached to a dirty page (e.g. a ceph snap).255 * Get a ref on a netfs group attached to a dirty page (e.g. a ceph snap).
244 */256 */
fs/netfs/locking.c+95−0
@@ -9,6 +9,11 @@ · 8 unmodified lines
9#include <linux/netfs.h>9#include <linux/netfs.h>
10#include "internal.h"10#include "internal.h"
11 11
12struct netfs_wb_waiter {
13 struct list_head link; /* Link in ictx->wb_queue */
14 struct task_struct *waiter; /* Waiter task; cleared when lock granted */
15};
16
12/*17/*
13 * inode_dio_wait_interruptible - wait for outstanding DIO requests to finish18 * inode_dio_wait_interruptible - wait for outstanding DIO requests to finish
14 * @inode: inode to wait for19 * @inode: inode to wait for
@@ -203,3 +208,93 @@ void netfs_end_io_direct(struct inode *inode) · 188 unmodified lines
203 up_read(&inode->i_rwsem);208 up_read(&inode->i_rwsem);
204}209}
205EXPORT_SYMBOL(netfs_end_io_direct);210EXPORT_SYMBOL(netfs_end_io_direct);
211
212/*
213 * Wait to have exclusive access to writeback.
214 */
215static bool netfs_wb_begin_wait(struct netfs_inode *ictx)
216{
217 struct netfs_wb_waiter waiter = {};
218 struct task_struct *tsk = current;
219 bool got = false;
220
221 spin_lock(&ictx->lock);
222
223 if (test_and_set_bit_lock(NETFS_ICTX_WB_LOCK, &ictx->flags)) {
224 get_task_struct(tsk);
225 waiter.waiter = tsk;
226 list_add_tail(&waiter.link, &ictx->wb_queue);
227 } else {
228 got = true;
229 }
230 spin_unlock(&ictx->lock);
231
232 if (!got) {
233 for (;;) {
234 set_current_state(TASK_UNINTERRUPTIBLE);
235 /* Read waiter before accessing inode state. */
236 if (smp_load_acquire(&waiter.waiter) == NULL)
237 break;
238 schedule();
239 }
240 }
241 __set_current_state(TASK_RUNNING);
242 return true;
243}
244
245/**
246 * netfs_wb_begin - Begin writeback, waiting if need be
247 * @ictx: The inode to get writeback access on
248 * @nowait: Return failure immediately rather than waiting if true
249 *
250 * Begin writeback to an inode, waiting for exclusive access if @nowait is
251 * false. This prevents collection from being done out of order with respect
252 * to the issuance of write subrequests.
253 *
254 * Note that writeback may be ended in a different process (e.g. the collection
255 * function on a workqueue) than started it.
256 *
257 * Return: True if can proceed, false if denied.
258 */
259bool netfs_wb_begin(struct netfs_inode *ictx, bool nowait)
260{
261 if (!test_and_set_bit_lock(NETFS_ICTX_WB_LOCK, &ictx->flags))
262 return true;
263 if (nowait) {
264 netfs_stat(&netfs_n_wb_lock_skip);
265 return false;
266 }
267 netfs_stat(&netfs_n_wb_lock_wait);
268 return netfs_wb_begin_wait(ictx);
269}
270EXPORT_SYMBOL(netfs_wb_begin);
271
272/* netfs_wb_end - End writeback
273 * @ictx: The inode we have writeback access to
274 *
275 * End writeback access on an inode, waking up the next writeback request.
276 */
277void netfs_wb_end(struct netfs_inode *ictx)
278{
279 struct netfs_wb_waiter *waiter;
280 struct task_struct *tsk;
281
282 WARN_ON_ONCE(!test_bit(NETFS_ICTX_WB_LOCK, &ictx->flags));
283
284 spin_lock(&ictx->lock);
285
286 waiter = list_first_entry_or_null(&ictx->wb_queue, struct netfs_wb_waiter, link);
287 if (waiter) {
288 list_del(&waiter->link);
289 tsk = waiter->waiter;
290 /* Write inode state before clearing waiter. */
291 smp_store_release(&waiter->waiter, NULL);
292 wake_up_process(tsk);
293 put_task_struct(tsk);
294 } else {
295 clear_bit_unlock(NETFS_ICTX_WB_LOCK, &ictx->flags);
296 }
297
298 spin_unlock(&ictx->lock);
299}
300EXPORT_SYMBOL(netfs_wb_end);
fs/netfs/read_retry.c+6−1
@@ -98,7 +98,12 @@ static void netfs_retry_read_subrequests(struct netfs_io_request *rreq) · 97 unmodified lines
98 goto abandon;98 goto abandon;
99 }99 }
100 100
101 list_for_each_continue(next, &stream->subrequests) {101 for (;;) {
102 /* Read pointer to subreq before reading subreq state. */
103 next = smp_load_acquire(&next->next);
104 if (next == &stream->subrequests)
105 break;
106
102 subreq = list_entry(next, struct netfs_io_subrequest, rreq_link);107 subreq = list_entry(next, struct netfs_io_subrequest, rreq_link);
103 if (subreq->start + subreq->transferred != start + len ||108 if (subreq->start + subreq->transferred != start + len ||
104 test_bit(NETFS_SREQ_BOUNDARY, &subreq->flags) ||109 test_bit(NETFS_SREQ_BOUNDARY, &subreq->flags) ||
fs/netfs/write_collect.c+10−0
@@ -408,6 +408,16 @@ bool netfs_write_collection(struct netfs_io_request *wreq) · 407 unmodified lines
408 netfs_wake_rreq_flag(wreq, NETFS_RREQ_IN_PROGRESS, netfs_rreq_trace_wake_ip);408 netfs_wake_rreq_flag(wreq, NETFS_RREQ_IN_PROGRESS, netfs_rreq_trace_wake_ip);
409 /* As we cleared NETFS_RREQ_IN_PROGRESS, we acquired its ref. */409 /* As we cleared NETFS_RREQ_IN_PROGRESS, we acquired its ref. */
410 410
411 switch (wreq->origin) {
412 case NETFS_WRITEBACK:
413 case NETFS_WRITEBACK_SINGLE:
414 case NETFS_WRITETHROUGH:
415 netfs_wb_end(ictx);
416 break;
417 default:
418 break;
419 }
420
411 if (wreq->iocb) {421 if (wreq->iocb) {
412 size_t written = min(wreq->transferred, wreq->len);422 size_t written = min(wreq->transferred, wreq->len);
413 wreq->iocb->ki_pos += written;423 wreq->iocb->ki_pos += written;
fs/netfs/write_issue.c+24−31
@@ -106,7 +106,7 @@ struct netfs_io_request *netfs_create_write_req(struct address_space *mapping, · 105 unmodified lines
106 _enter("R=%x", wreq->debug_id);106 _enter("R=%x", wreq->debug_id);
107 107
108 ictx = netfs_inode(wreq->inode);108 ictx = netfs_inode(wreq->inode);
109 if (is_cacheable && netfs_is_cache_enabled(ictx))109 if (is_cacheable)
110 fscache_begin_write_operation(&wreq->cache_resources, netfs_i_cookie(ictx));110 fscache_begin_write_operation(&wreq->cache_resources, netfs_i_cookie(ictx));
111 if (rolling_buffer_init(&wreq->buffer, wreq->debug_id, ITER_SOURCE) < 0)111 if (rolling_buffer_init(&wreq->buffer, wreq->debug_id, ITER_SOURCE) < 0)
112 goto nomem;112 goto nomem;
@@ -551,14 +551,8 @@ int netfs_writepages(struct address_space *mapping, · 438 unmodified lines
551 struct folio *folio;551 struct folio *folio;
552 int error = 0;552 int error = 0;
553 553
554 if (!mutex_trylock(&ictx->wb_lock)) {554 if (!netfs_wb_begin(ictx, wbc->sync_mode == WB_SYNC_NONE))
555 if (wbc->sync_mode == WB_SYNC_NONE) {555 return 0;
556 netfs_stat(&netfs_n_wb_lock_skip);
557 return 0;
558 }
559 netfs_stat(&netfs_n_wb_lock_wait);
560 mutex_lock(&ictx->wb_lock);
561 }
562 556
563 /* Need the first folio to be able to set up the op. */557 /* Need the first folio to be able to set up the op. */
564 folio = writeback_iter(mapping, wbc, NULL, &error);558 folio = writeback_iter(mapping, wbc, NULL, &error);
@@ -588,13 +582,13 @@ int netfs_writepages(struct address_space *mapping, · 23 unmodified lines
588 }582 }
589 583
590 error = netfs_write_folio(wreq, wbc, folio);584 error = netfs_write_folio(wreq, wbc, folio);
591 if (error < 0)585 if (error == -ENOMEM) {
592 break;586 folio_redirty_for_writepage(wbc, folio);
587 folio_unlock(folio);
588 }
593 } while ((folio = writeback_iter(mapping, wbc, folio, &error)));589 } while ((folio = writeback_iter(mapping, wbc, folio, &error)));
594 590
595 netfs_end_issue_write(wreq);591 netfs_end_issue_write(wreq);
596
597 mutex_unlock(&ictx->wb_lock);
598 netfs_wake_collector(wreq);592 netfs_wake_collector(wreq);
599 593
600 netfs_put_request(wreq, netfs_rreq_trace_put_return);594 netfs_put_request(wreq, netfs_rreq_trace_put_return);
@@ -602,9 +596,16 @@ int netfs_writepages(struct address_space *mapping, · 1 unmodified line
602 return error;596 return error;
603 597
604couldnt_start:598couldnt_start:
605 netfs_kill_dirty_pages(mapping, wbc, folio);599 if (error == -ENOMEM) {
600 folio_redirty_for_writepage(wbc, folio);
601 folio_unlock(folio);
602 folio = writeback_iter(mapping, wbc, folio, &error);
603 WARN_ON_ONCE(folio != NULL);
604 } else {
605 netfs_kill_dirty_pages(mapping, wbc, folio);
606 }
606out:607out:
607 mutex_unlock(&ictx->wb_lock);608 netfs_wb_end(ictx);
608 _leave(" = %d", error);609 _leave(" = %d", error);
609 return error;610 return error;
610}611}
@@ -618,16 +619,17 @@ struct netfs_io_request *netfs_begin_writethrough(struct kiocb *iocb, size_t len · 7 unmodified lines
618 struct netfs_io_request *wreq = NULL;619 struct netfs_io_request *wreq = NULL;
619 struct netfs_inode *ictx = netfs_inode(file_inode(iocb->ki_filp));620 struct netfs_inode *ictx = netfs_inode(file_inode(iocb->ki_filp));
620 621
621 mutex_lock(&ictx->wb_lock);622 netfs_wb_begin(ictx, false);
622 623
623 wreq = netfs_create_write_req(iocb->ki_filp->f_mapping, iocb->ki_filp,624 wreq = netfs_create_write_req(iocb->ki_filp->f_mapping, iocb->ki_filp,
624 iocb->ki_pos, NETFS_WRITETHROUGH);625 iocb->ki_pos, NETFS_WRITETHROUGH);
625 if (IS_ERR(wreq)) {626 if (IS_ERR(wreq)) {
626 mutex_unlock(&ictx->wb_lock);627 netfs_wb_end(ictx);
627 return wreq;628 return wreq;
628 }629 }
629 630
630 wreq->io_streams[0].avail = true;631 wreq->io_streams[0].avail = true;
632 __set_bit(NETFS_RREQ_OFFLOAD_COLLECTION, &wreq->flags);
631 trace_netfs_write(wreq, netfs_write_trace_writethrough);633 trace_netfs_write(wreq, netfs_write_trace_writethrough);
632 return wreq;634 return wreq;
633}635}
@@ -685,7 +687,6 @@ int netfs_advance_writethrough(struct netfs_io_request *wreq, struct writeback_c · 51 unmodified lines
685ssize_t netfs_end_writethrough(struct netfs_io_request *wreq, struct writeback_control *wbc,687ssize_t netfs_end_writethrough(struct netfs_io_request *wreq, struct writeback_control *wbc,
686 struct folio *writethrough_cache)688 struct folio *writethrough_cache)
687{689{
688 struct netfs_inode *ictx = netfs_inode(wreq->inode);
689 ssize_t ret;690 ssize_t ret;
690 691
691 _enter("R=%x", wreq->debug_id);692 _enter("R=%x", wreq->debug_id);
@@ -699,8 +700,6 @@ ssize_t netfs_end_writethrough(struct netfs_io_request *wreq, struct writeback_c · 7 unmodified lines
699 700
700 netfs_end_issue_write(wreq);701 netfs_end_issue_write(wreq);
701 702
702 mutex_unlock(&ictx->wb_lock);
703
704 if (wreq->iocb)703 if (wreq->iocb)
705 ret = -EIOCBQUEUED;704 ret = -EIOCBQUEUED;
706 else705 else
@@ -847,15 +846,10 @@ int netfs_writeback_single(struct address_space *mapping, · 140 unmodified lines
847 if (WARN_ON_ONCE(!iov_iter_is_folioq(iter)))846 if (WARN_ON_ONCE(!iov_iter_is_folioq(iter)))
848 return -EIO;847 return -EIO;
849 848
850 if (!mutex_trylock(&ictx->wb_lock)) {849 if (!netfs_wb_begin(ictx, wbc->sync_mode == WB_SYNC_NONE)) {
851 if (wbc->sync_mode == WB_SYNC_NONE) {850 /* The VFS will have undirtied the inode. */
852 /* The VFS will have undirtied the inode. */851 netfs_single_mark_inode_dirty(&ictx->inode);
853 netfs_single_mark_inode_dirty(&ictx->inode);852 return 1;
854 netfs_stat(&netfs_n_wb_lock_skip);
855 return 1;
856 }
857 netfs_stat(&netfs_n_wb_lock_wait);
858 mutex_lock(&ictx->wb_lock);
859 }853 }
860 854
861 wreq = netfs_create_write_req(mapping, NULL, 0, NETFS_WRITEBACK_SINGLE);855 wreq = netfs_create_write_req(mapping, NULL, 0, NETFS_WRITEBACK_SINGLE);
@@ -893,7 +887,6 @@ stop: · 31 unmodified lines
893 smp_wmb(); /* Write lists before ALL_QUEUED. */887 smp_wmb(); /* Write lists before ALL_QUEUED. */
894 set_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags);888 set_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags);
895 889
896 mutex_unlock(&ictx->wb_lock);
897 netfs_wake_collector(wreq);890 netfs_wake_collector(wreq);
898 891
899 netfs_put_request(wreq, netfs_rreq_trace_put_return);892 netfs_put_request(wreq, netfs_rreq_trace_put_return);
@@ -901,7 +894,7 @@ stop: · 1 unmodified line
901 return ret;894 return ret;
902 895
903couldnt_start:896couldnt_start:
904 mutex_unlock(&ictx->wb_lock);897 netfs_wb_end(ictx);
905 _leave(" = %d", ret);898 _leave(" = %d", ret);
906 return ret;899 return ret;
907}900}
fs/netfs/write_retry.c+6−1
@@ -72,7 +72,12 @@ static void netfs_retry_write_stream(struct netfs_io_request *wreq, · 71 unmodified lines
72 !test_bit(NETFS_SREQ_NEED_RETRY, &from->flags))72 !test_bit(NETFS_SREQ_NEED_RETRY, &from->flags))
73 return;73 return;
74 74
75 list_for_each_continue(next, &stream->subrequests) {75 for (;;) {
76 /* Read pointer to subreq before reading subreq state. */
77 next = smp_load_acquire(&next->next);
78 if (next == &stream->subrequests)
79 break;
80
76 subreq = list_entry(next, struct netfs_io_subrequest, rreq_link);81 subreq = list_entry(next, struct netfs_io_subrequest, rreq_link);
77 if (subreq->start + subreq->transferred != start + len ||82 if (subreq->start + subreq->transferred != start + len ||
78 test_bit(NETFS_SREQ_BOUNDARY, &subreq->flags) ||83 test_bit(NETFS_SREQ_BOUNDARY, &subreq->flags) ||
fs/ntfs/aops.c+2−4
@@ -38,11 +38,9 @@ static void ntfs_iomap_read_end_io(struct bio *bio) · 37 unmodified lines
38}38}
39 39
40static void ntfs_iomap_bio_submit_read(const struct iomap_iter *iter,40static void ntfs_iomap_bio_submit_read(const struct iomap_iter *iter,
41 struct iomap_read_folio_ctx *ctx)41 struct iomap_read_folio_ctx *ctx)
42{42{
43 struct bio *bio = ctx->read_ctx;43 iomap_bio_submit_read_endio(iter, ctx, ntfs_iomap_read_end_io);
44 bio->bi_end_io = ntfs_iomap_read_end_io;
45 submit_bio(bio);
46}44}
47 45
48static const struct iomap_read_ops ntfs_iomap_bio_read_ops = {46static const struct iomap_read_ops ntfs_iomap_bio_read_ops = {
fs/ntfs3/inode.c+1−4
@@ -608,10 +608,7 @@ static void ntfs_iomap_read_end_io(struct bio *bio) · 607 unmodified lines
608static void ntfs_iomap_bio_submit_read(const struct iomap_iter *iter,608static void ntfs_iomap_bio_submit_read(const struct iomap_iter *iter,
609 struct iomap_read_folio_ctx *ctx)609 struct iomap_read_folio_ctx *ctx)
610{610{
611 struct bio *bio = ctx->read_ctx;611 iomap_bio_submit_read_endio(iter, ctx, ntfs_iomap_read_end_io);
612
613 bio->bi_end_io = ntfs_iomap_read_end_io;
614 submit_bio(bio);
615}612}
616 613
617static const struct iomap_read_ops ntfs_iomap_bio_read_ops = {614static const struct iomap_read_ops ntfs_iomap_bio_read_ops = {
fs/orangefs/dir.c+4−3
@@ -191,7 +191,8 @@ static int fill_from_part(struct orangefs_dir_part *part, · 190 unmodified lines
191{191{
192 const int offset = sizeof(struct orangefs_readdir_response_s);192 const int offset = sizeof(struct orangefs_readdir_response_s);
193 struct orangefs_khandle *khandle;193 struct orangefs_khandle *khandle;
194 __u32 *len, padlen;194 __u32 *len;
195 u64 padlen;
195 loff_t i;196 loff_t i;
196 char *s;197 char *s;
197 i = ctx->pos & ~PART_MASK;198 i = ctx->pos & ~PART_MASK;
@@ -215,8 +216,8 @@ static int fill_from_part(struct orangefs_dir_part *part, · 17 unmodified lines
215 * len is the size of the string itself. padlen is the216 * len is the size of the string itself. padlen is the
216 * total size of the encoded string.217 * total size of the encoded string.
217 */218 */
218 padlen = (sizeof *len + *len + 1) +219 padlen = (u64)sizeof *len + *len + 1;
219 (8 - (sizeof *len + *len + 1)%8)%8;220 padlen += (8 - padlen % 8) % 8;
220 if (part->len < i + padlen + sizeof *khandle)221 if (part->len < i + padlen + sizeof *khandle)
221 goto next;222 goto next;
222 s = (void *)part + offset + i + sizeof *len;223 s = (void *)part + offset + i + sizeof *len;
fs/overlayfs/copy_up.c+10−2
@@ -853,7 +853,7 @@ static int ovl_copy_up_tmpfile(struct ovl_copy_up_ctx *c) · 852 unmodified lines
853{853{
854 struct ovl_fs *ofs = OVL_FS(c->dentry->d_sb);854 struct ovl_fs *ofs = OVL_FS(c->dentry->d_sb);
855 struct inode *udir = d_inode(c->destdir);855 struct inode *udir = d_inode(c->destdir);
856 struct dentry *temp, *upper;856 struct dentry *temp, *upper, *newdentry = NULL;
857 struct file *tmpfile;857 struct file *tmpfile;
858 int err;858 int err;
859 859
@@ -889,6 +889,14 @@ static int ovl_copy_up_tmpfile(struct ovl_copy_up_ctx *c) · 29 unmodified lines
889 err = PTR_ERR(upper);889 err = PTR_ERR(upper);
890 if (!IS_ERR(upper)) {890 if (!IS_ERR(upper)) {
891 err = ovl_do_link(ofs, temp, udir, upper);891 err = ovl_do_link(ofs, temp, udir, upper);
892 if (!err) {
893 /*
894 * Record the linked dentry -- not the disconnected
895 * O_TMPFILE dentry -- so that ->d_revalidate() on
896 * the upper fs sees the real parent/name.
897 */
898 newdentry = dget(upper);
899 }
892 end_creating(upper);900 end_creating(upper);
893 }901 }
894 902
@@ -903,7 +911,7 @@ static int ovl_copy_up_tmpfile(struct ovl_copy_up_ctx *c) · 8 unmodified lines
903 911
904 if (!c->metacopy)912 if (!c->metacopy)
905 ovl_set_upperdata(d_inode(c->dentry));913 ovl_set_upperdata(d_inode(c->dentry));
906 ovl_inode_update(d_inode(c->dentry), dget(temp));914 ovl_inode_update(d_inode(c->dentry), newdentry);
907 915
908out:916out:
909 ovl_end_write(c->dentry);917 ovl_end_write(c->dentry);
fs/overlayfs/inode.c+2−2
@@ -783,8 +783,8 @@ static const struct address_space_operations ovl_aops = { · 782 unmodified lines
783 *783 *
784 * This chain is valid:784 * This chain is valid:
785 * - inode->i_rwsem (inode_lock[2])785 * - inode->i_rwsem (inode_lock[2])
786 * - upper_mnt->mnt_sb->s_writers (ovl_want_write[0])
787 * - OVL_I(inode)->lock (ovl_inode_lock[2])786 * - OVL_I(inode)->lock (ovl_inode_lock[2])
787 * - upper_mnt->mnt_sb->s_writers (ovl_want_write[0])
788 * - OVL_I(lowerinode)->lock (ovl_inode_lock[1])788 * - OVL_I(lowerinode)->lock (ovl_inode_lock[1])
789 *789 *
790 * And this chain is valid:790 * And this chain is valid:
@@ -797,8 +797,8 @@ static const struct address_space_operations ovl_aops = { · 6 unmodified lines
797 * held, because it is in reverse order of the non-nested case using the same797 * held, because it is in reverse order of the non-nested case using the same
798 * upper fs:798 * upper fs:
799 * - inode->i_rwsem (inode_lock[1])799 * - inode->i_rwsem (inode_lock[1])
800 * - upper_mnt->mnt_sb->s_writers (ovl_want_write[0])
801 * - OVL_I(inode)->lock (ovl_inode_lock[1])800 * - OVL_I(inode)->lock (ovl_inode_lock[1])
801 * - upper_mnt->mnt_sb->s_writers (ovl_want_write[0])
802 */802 */
803#define OVL_MAX_NESTING FILESYSTEM_MAX_STACK_DEPTH803#define OVL_MAX_NESTING FILESYSTEM_MAX_STACK_DEPTH
804 804
fs/proc/generic.c+4−5
@@ -112,6 +112,8 @@ static bool pde_subdir_insert(struct proc_dir_entry *dir, · 111 unmodified lines
112 /* Add new node and rebalance tree. */112 /* Add new node and rebalance tree. */
113 rb_link_node(&de->subdir_node, parent, new);113 rb_link_node(&de->subdir_node, parent, new);
114 rb_insert_color(&de->subdir_node, root);114 rb_insert_color(&de->subdir_node, root);
115 if (S_ISDIR(de->mode))
116 dir->nlink++;
115 return true;117 return true;
116}118}
117 119
@@ -404,7 +406,6 @@ struct proc_dir_entry *proc_register(struct proc_dir_entry *dir, · 286 unmodified lines
404 write_unlock(&proc_subdir_lock);406 write_unlock(&proc_subdir_lock);
405 goto out_free_inum;407 goto out_free_inum;
406 }408 }
407 dir->nlink++;
408 write_unlock(&proc_subdir_lock);409 write_unlock(&proc_subdir_lock);
409 410
410 return dp;411 return dp;
@@ -706,6 +707,8 @@ static void pde_erase(struct proc_dir_entry *pde, struct proc_dir_entry *parent) · 295 unmodified lines
706{707{
707 rb_erase(&pde->subdir_node, &parent->subdir);708 rb_erase(&pde->subdir_node, &parent->subdir);
708 RB_CLEAR_NODE(&pde->subdir_node);709 RB_CLEAR_NODE(&pde->subdir_node);
710 if (S_ISDIR(pde->mode))
711 parent->nlink--;
709}712}
710 713
711/*714/*
@@ -731,8 +734,6 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent) · 19 unmodified lines
731 de = NULL;734 de = NULL;
732 } else {735 } else {
733 pde_erase(de, parent);736 pde_erase(de, parent);
734 if (S_ISDIR(de->mode))
735 parent->nlink--;
736 }737 }
737 }738 }
738 write_unlock(&proc_subdir_lock);739 write_unlock(&proc_subdir_lock);
@@ -791,8 +792,6 @@ int remove_proc_subtree(const char *name, struct proc_dir_entry *parent) · 52 unmodified lines
791 continue;792 continue;
792 }793 }
793 next = de->parent;794 next = de->parent;
794 if (S_ISDIR(de->mode))
795 next->nlink--;
796 write_unlock(&proc_subdir_lock);795 write_unlock(&proc_subdir_lock);
797 796
798 proc_entry_rundown(de);797 proc_entry_rundown(de);
fs/xfs/xfs_aops.c+1−2
@@ -764,8 +764,7 @@ xfs_bio_submit_read( · 763 unmodified lines
764 764
765 /* defer read completions to the ioend workqueue */765 /* defer read completions to the ioend workqueue */
766 iomap_init_ioend(iter->inode, bio, ctx->read_ctx_file_offset, 0);766 iomap_init_ioend(iter->inode, bio, ctx->read_ctx_file_offset, 0);
767 bio->bi_end_io = xfs_end_bio;767 iomap_bio_submit_read_endio(iter, ctx, xfs_end_bio);
768 submit_bio(bio);
769}768}
770 769
771static const struct iomap_read_ops xfs_iomap_read_ops = {770static const struct iomap_read_ops xfs_iomap_read_ops = {
fs/xfs/xfs_super.c+3−0
@@ -534,8 +534,11 @@ xfs_open_devices( · 533 unmodified lines
534 out_free_rtdev_targ:534 out_free_rtdev_targ:
535 if (mp->m_rtdev_targp)535 if (mp->m_rtdev_targp)
536 xfs_free_buftarg(mp->m_rtdev_targp);536 xfs_free_buftarg(mp->m_rtdev_targp);
537 mp->m_rtdev_targp = NULL;
538 rtdev_file = NULL; /* released by xfs_free_buftarg() */
537 out_free_ddev_targ:539 out_free_ddev_targ:
538 xfs_free_buftarg(mp->m_ddev_targp);540 xfs_free_buftarg(mp->m_ddev_targp);
541 mp->m_ddev_targp = NULL;
539 out_close_rtdev:542 out_close_rtdev:
540 if (rtdev_file)543 if (rtdev_file)
541 bdev_fput(rtdev_file);544 bdev_fput(rtdev_file);
include/linux/iomap.h+2−0
@@ -622,6 +622,8 @@ extern struct bio_set iomap_ioend_bioset; · 621 unmodified lines
622#ifdef CONFIG_BLOCK622#ifdef CONFIG_BLOCK
623int iomap_bio_read_folio_range(const struct iomap_iter *iter,623int iomap_bio_read_folio_range(const struct iomap_iter *iter,
624 struct iomap_read_folio_ctx *ctx, size_t plen);624 struct iomap_read_folio_ctx *ctx, size_t plen);
625void iomap_bio_submit_read_endio(const struct iomap_iter *iter,
626 struct iomap_read_folio_ctx *ctx, bio_end_io_t end_io);
625 627
626extern const struct iomap_read_ops iomap_bio_read_ops;628extern const struct iomap_read_ops iomap_bio_read_ops;
627 629
include/linux/netfs.h+10−3
@@ -61,14 +61,16 @@ struct netfs_inode { · 60 unmodified lines
61#if IS_ENABLED(CONFIG_FSCACHE)61#if IS_ENABLED(CONFIG_FSCACHE)
62 struct fscache_cookie *cache;62 struct fscache_cookie *cache;
63#endif63#endif
64 struct mutex wb_lock; /* Writeback serialisation */64 struct list_head wb_queue; /* Queue of processes wanting to do writeback */
65 loff_t _remote_i_size; /* Size of the remote file */65 loff_t _remote_i_size; /* Size of the remote file */
66 loff_t _zero_point; /* Size after which we assume there's no data66 loff_t _zero_point; /* Size after which we assume there's no data
67 * on the server */67 * on the server */
68 spinlock_t lock; /* Lock covering wb_queue */
68 atomic_t io_count; /* Number of outstanding reqs */69 atomic_t io_count; /* Number of outstanding reqs */
69 unsigned long flags;70 unsigned long flags;
70#define NETFS_ICTX_ODIRECT 0 /* The file has DIO in progress */71#define NETFS_ICTX_ODIRECT 0 /* The file has DIO in progress */
71#define NETFS_ICTX_UNBUFFERED 1 /* I/O should not use the pagecache */72#define NETFS_ICTX_UNBUFFERED 1 /* I/O should not use the pagecache */
73#define NETFS_ICTX_WB_LOCK 2 /* Writeback serialisation lock */
72#define NETFS_ICTX_MODIFIED_ATTR 3 /* Indicate change in mtime/ctime */74#define NETFS_ICTX_MODIFIED_ATTR 3 /* Indicate change in mtime/ctime */
73#define NETFS_ICTX_SINGLE_NO_UPLOAD 4 /* Monolithic payload, cache but no upload */75#define NETFS_ICTX_SINGLE_NO_UPLOAD 4 /* Monolithic payload, cache but no upload */
74};76};
@@ -462,6 +464,10 @@ int netfs_alloc_folioq_buffer(struct address_space *mapping, · 387 unmodified lines
462 size_t *_cur_size, ssize_t size, gfp_t gfp);464 size_t *_cur_size, ssize_t size, gfp_t gfp);
463void netfs_free_folioq_buffer(struct folio_queue *fq);465void netfs_free_folioq_buffer(struct folio_queue *fq);
464 466
467/* Writeback exclusion API. */
468bool netfs_wb_begin(struct netfs_inode *ictx, bool nowait);
469void netfs_wb_end(struct netfs_inode *ictx);
470
465/**471/**
466 * netfs_inode - Get the netfs inode context from the inode472 * netfs_inode - Get the netfs inode context from the inode
467 * @inode: The inode to query473 * @inode: The inode to query
@@ -743,7 +749,8 @@ static inline void netfs_inode_init(struct netfs_inode *ctx, · 275 unmodified lines
743#if IS_ENABLED(CONFIG_FSCACHE)749#if IS_ENABLED(CONFIG_FSCACHE)
744 ctx->cache = NULL;750 ctx->cache = NULL;
745#endif751#endif
746 mutex_init(&ctx->wb_lock);752 INIT_LIST_HEAD(&ctx->wb_queue);
753 spin_lock_init(&ctx->lock);
747 /* ->releasepage() drives zero_point */754 /* ->releasepage() drives zero_point */
748 if (use_zero_point) {755 if (use_zero_point) {
749 ctx->_zero_point = ctx->_remote_i_size;756 ctx->_zero_point = ctx->_remote_i_size;
@@ -753,7 +760,7 @@ static inline void netfs_inode_init(struct netfs_inode *ctx, · 3 unmodified lines
753 760
754/**761/**
755 * netfs_resize_file - Note that a file got resized762 * netfs_resize_file - Note that a file got resized
756 * @ctx: The netfs inode being resized763 * @ictx: The netfs inode being resized
757 * @new_i_size: The new file size764 * @new_i_size: The new file size
758 * @changed_on_server: The change was applied to the server765 * @changed_on_server: The change was applied to the server
759 *766 *
lib/iov_iter.c+19−1
@@ -1568,6 +1568,7 @@ static ssize_t iov_iter_extract_xarray_pages(struct iov_iter *i, · 1567 unmodified lines
1568 struct folio *folio;1568 struct folio *folio;
1569 unsigned int nr = 0, offset;1569 unsigned int nr = 0, offset;
1570 loff_t pos = i->xarray_start + i->iov_offset;1570 loff_t pos = i->xarray_start + i->iov_offset;
1571 bool will_alloc = !*pages;
1571 XA_STATE(xas, i->xarray, pos >> PAGE_SHIFT);1572 XA_STATE(xas, i->xarray, pos >> PAGE_SHIFT);
1572 1573
1573 offset = pos & ~PAGE_MASK;1574 offset = pos & ~PAGE_MASK;
@@ -1595,6 +1596,14 @@ static ssize_t iov_iter_extract_xarray_pages(struct iov_iter *i, · 21 unmodified lines
1595 }1596 }
1596 rcu_read_unlock();1597 rcu_read_unlock();
1597 1598
1599 if (!nr) {
1600 if (will_alloc) {
1601 kvfree(*pages);
1602 *pages = NULL;
1603 }
1604 return 0;
1605 }
1606
1598 maxsize = min_t(size_t, nr * PAGE_SIZE - offset, maxsize);1607 maxsize = min_t(size_t, nr * PAGE_SIZE - offset, maxsize);
1599 iov_iter_advance(i, maxsize);1608 iov_iter_advance(i, maxsize);
1600 return maxsize;1609 return maxsize;
@@ -1628,6 +1637,8 @@ static ssize_t iov_iter_extract_bvec_pages(struct iov_iter *i, · 27 unmodified lines
1628 bi.bi_bvec_done = skip;1637 bi.bi_bvec_done = skip;
1629 1638
1630 maxpages = want_pages_array(pages, maxsize, skip, maxpages);1639 maxpages = want_pages_array(pages, maxsize, skip, maxpages);
1640 if (!maxpages)
1641 return -ENOMEM;
1631 1642
1632 while (bi.bi_size && bi.bi_idx < i->nr_segs) {1643 while (bi.bi_size && bi.bi_idx < i->nr_segs) {
1633 struct bio_vec bv = bvec_iter_bvec(i->bvec, bi);1644 struct bio_vec bv = bvec_iter_bvec(i->bvec, bi);
@@ -1745,6 +1756,7 @@ static ssize_t iov_iter_extract_user_pages(struct iov_iter *i, · 111 unmodified lines
1745 unsigned long addr;1756 unsigned long addr;
1746 unsigned int gup_flags = 0;1757 unsigned int gup_flags = 0;
1747 size_t offset;1758 size_t offset;
1759 bool will_alloc = !*pages;
1748 int res;1760 int res;
1749 1761
1750 if (i->data_source == ITER_DEST)1762 if (i->data_source == ITER_DEST)
@@ -1761,8 +1773,14 @@ static ssize_t iov_iter_extract_user_pages(struct iov_iter *i, · 10 unmodified lines
1761 if (!maxpages)1773 if (!maxpages)
1762 return -ENOMEM;1774 return -ENOMEM;
1763 res = pin_user_pages_fast(addr, maxpages, gup_flags, *pages);1775 res = pin_user_pages_fast(addr, maxpages, gup_flags, *pages);
1764 if (unlikely(res <= 0))1776 if (unlikely(res <= 0)) {
1777 if (will_alloc) {
1778 kvfree(*pages);
1779 *pages = NULL;
1780 }
1765 return res;1781 return res;
1782 }
1783
1766 maxsize = min_t(size_t, maxsize, res * PAGE_SIZE - offset);1784 maxsize = min_t(size_t, maxsize, res * PAGE_SIZE - offset);
1767 iov_iter_advance(i, maxsize);1785 iov_iter_advance(i, maxsize);
1768 return maxsize;1786 return maxsize;
lib/scatterlist.c+1−0
@@ -1366,6 +1366,7 @@ static ssize_t extract_xarray_to_sg(struct iov_iter *iter, · 1365 unmodified lines
1366 sg_max--;1366 sg_max--;
1367 1367
1368 maxsize -= len;1368 maxsize -= len;
1369 start += len;
1369 ret += len;1370 ret += len;
1370 if (maxsize <= 0 || sg_max == 0)1371 if (maxsize <= 0 || sg_max == 0)
1371 break;1372 break;
lib/tests/kunit_iov_iter.c+2−3
@@ -283,7 +283,7 @@ static void __init iov_kunit_copy_to_bvec(struct kunit *test) · 282 unmodified lines
283 struct page **spages, **bpages;283 struct page **spages, **bpages;
284 u8 *scratch, *buffer;284 u8 *scratch, *buffer;
285 size_t bufsize, npages, size, copied;285 size_t bufsize, npages, size, copied;
286 int i, b, patt;286 int i, patt;
287 287
288 bufsize = 0x100000;288 bufsize = 0x100000;
289 npages = bufsize / PAGE_SIZE;289 npages = bufsize / PAGE_SIZE;
@@ -306,10 +306,9 @@ static void __init iov_kunit_copy_to_bvec(struct kunit *test) · 16 unmodified lines
306 KUNIT_EXPECT_EQ(test, iter.nr_segs, 0);306 KUNIT_EXPECT_EQ(test, iter.nr_segs, 0);
307 307
308 /* Build the expected image in the scratch buffer. */308 /* Build the expected image in the scratch buffer. */
309 b = 0;
310 patt = 0;309 patt = 0;
311 memset(scratch, 0, bufsize);310 memset(scratch, 0, bufsize);
312 for (pr = bvec_test_ranges; pr->from >= 0; pr++, b++) {311 for (pr = bvec_test_ranges; pr->from >= 0; pr++) {
313 u8 *p = scratch + pr->page * PAGE_SIZE;312 u8 *p = scratch + pr->page * PAGE_SIZE;
314 313
315 for (i = pr->from; i < pr->to; i++)314 for (i = pr->from; i < pr->to; i++)
tools/testing/selftests/filesystems/.gitignore+1−0
@@ -5,3 +5,4 @@ fclog · 4 unmodified lines
5file_stressor5file_stressor
6anon_inode_test6anon_inode_test
7kernfs_test7kernfs_test
8idmapped_tmpfile
tools/testing/selftests/filesystems/Makefile+4−0
@@ -2,6 +2,10 @@ · 1 unmodified line
2 2
3CFLAGS += $(KHDR_INCLUDES)3CFLAGS += $(KHDR_INCLUDES)
4TEST_GEN_PROGS := devpts_pts file_stressor anon_inode_test kernfs_test fclog4TEST_GEN_PROGS := devpts_pts file_stressor anon_inode_test kernfs_test fclog
5TEST_GEN_PROGS += idmapped_tmpfile
5TEST_GEN_PROGS_EXTENDED := dnotify_test6TEST_GEN_PROGS_EXTENDED := dnotify_test
6 7
7include ../lib.mk8include ../lib.mk
9
10$(OUTPUT)/idmapped_tmpfile: LDLIBS += -lcap
11$(OUTPUT)/idmapped_tmpfile: utils.c
tools/testing/selftests/filesystems/idmapped_tmpfile.c+168−0
@@ -0,0 +1,168 @@
1// SPDX-License-Identifier: GPL-2.0
2#define _GNU_SOURCE
3
4#include <errno.h>
5#include <fcntl.h>
6#include <limits.h>
7#include <sched.h>
8#include <stdio.h>
9#include <unistd.h>
10#include <sys/fsuid.h>
11#include <sys/stat.h>
12#include <sys/syscall.h>
13
14#include <linux/mount.h>
15#include <linux/types.h>
16
17#include "kselftest_harness.h"
18#include "wrappers.h"
19#include "utils.h"
20
21/*
22 * The test mount maps caller-visible ids [0, MAP_RANGE) onto the on-disk range
23 * [MAP_HOST, MAP_HOST + MAP_RANGE). An id outside [0, MAP_RANGE) therefore has
24 * no mapping in the mount and is not representable in the filesystem.
25 */
26#define MAP_HOST 10000
27#define MAP_RANGE 10000
28#define UNMAPPED 50000
29
30#ifndef MOUNT_ATTR_IDMAP
31#define MOUNT_ATTR_IDMAP 0x00100000
32#endif
33
34#ifndef __NR_mount_setattr
35#define __NR_mount_setattr 442
36#endif
37
38static inline int sys_mount_setattr(int dfd, const char *path,
39 unsigned int flags,
40 struct mount_attr *attr, size_t size)
41{
42 return syscall(__NR_mount_setattr, dfd, path, flags, attr, size);
43}
44
45/*
46 * Clone @path into a detached mount idmapped so that caller-visible ids
47 * [0, MAP_RANGE) map onto the on-disk ids [MAP_HOST, MAP_HOST + MAP_RANGE).
48 * Returns the mount fd, or -1 if idmapped mounts are not available.
49 */
50static int idmapped_clone(const char *path)
51{
52 struct mount_attr attr = {
53 .attr_set = MOUNT_ATTR_IDMAP,
54 };
55 int fd_tree, userns_fd, ret;
56
57 fd_tree = sys_open_tree(AT_FDCWD, path,
58 OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC);
59 if (fd_tree < 0)
60 return -1;
61
62 userns_fd = get_userns_fd(MAP_HOST, 0, MAP_RANGE);
63 if (userns_fd < 0) {
64 close(fd_tree);
65 return -1;
66 }
67
68 attr.userns_fd = userns_fd;
69 ret = sys_mount_setattr(fd_tree, "", AT_EMPTY_PATH, &attr, sizeof(attr));
70 close(userns_fd);
71 if (ret) {
72 close(fd_tree);
73 return -1;
74 }
75
76 return fd_tree;
77}
78
79FIXTURE(idmapped_tmpfile) {
80 char dir[64]; /* non-idmapped path to the layer directory */
81};
82
83FIXTURE_SETUP(idmapped_tmpfile)
84{
85 /* Private mount namespace so test mounts need no cleanup. */
86 ASSERT_EQ(unshare(CLONE_NEWNS), 0);
87 ASSERT_EQ(sys_mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL), 0);
88 ASSERT_EQ(sys_mount("tmpfs", "/tmp", "tmpfs", 0, NULL), 0);
89
90 snprintf(self->dir, sizeof(self->dir), "/tmp/d");
91 ASSERT_EQ(mkdir(self->dir, 0777), 0);
92 /* World-writable so an unmapped caller still passes permission(). */
93 ASSERT_EQ(chmod(self->dir, 0777), 0);
94}
95
96FIXTURE_TEARDOWN(idmapped_tmpfile)
97{
98}
99
100/*
101 * A caller whose fsuid/fsgid have no mapping in the idmapped mount must not be
102 * able to create an O_TMPFILE. Without the check in vfs_tmpfile() the inode
103 * would be created owned by (uid_t)-1 and could then be linked into the
104 * namespace.
105 */
106TEST_F(idmapped_tmpfile, unmapped_caller_is_refused)
107{
108 int mfd, fd;
109
110 mfd = idmapped_clone(self->dir);
111 if (mfd < 0)
112 SKIP(return, "idmapped mounts not supported");
113
114 /* Become a caller outside the mount's [0, MAP_RANGE) range. */
115 setfsgid(UNMAPPED);
116 setfsuid(UNMAPPED);
117 ASSERT_EQ(setfsuid(-1), UNMAPPED);
118
119 fd = openat(mfd, ".", O_TMPFILE | O_WRONLY, 0644);
120 ASSERT_LT(fd, 0);
121 EXPECT_EQ(errno, EOVERFLOW);
122 if (fd >= 0)
123 close(fd);
124
125 EXPECT_EQ(close(mfd), 0);
126}
127
128/*
129 * A mapped caller can create an O_TMPFILE and link it into the namespace; the
130 * ownership round-trips through the mount idmap. This is what makes refusing
131 * the unmapped case above necessary in the first place.
132 */
133TEST_F(idmapped_tmpfile, mapped_caller_creates_and_links)
134{
135 char path[PATH_MAX];
136 struct stat st;
137 int mfd, fd;
138
139 mfd = idmapped_clone(self->dir);
140 if (mfd < 0)
141 SKIP(return, "idmapped mounts not supported");
142
143 /* Caller is uid/gid 0, which maps to MAP_HOST through the mount. */
144 fd = openat(mfd, ".", O_TMPFILE | O_RDWR, 0600);
145 ASSERT_GE(fd, 0);
146
147 ASSERT_EQ(fstat(fd, &st), 0);
148 EXPECT_EQ(st.st_uid, 0);
149 EXPECT_EQ(st.st_gid, 0);
150
151 /* The tmpfile is linkable: splice it into the directory. */
152 ASSERT_EQ(linkat(fd, "", mfd, "linked", AT_EMPTY_PATH), 0);
153 EXPECT_EQ(close(fd), 0);
154
155 ASSERT_EQ(fstatat(mfd, "linked", &st, 0), 0);
156 EXPECT_EQ(st.st_uid, 0);
157 EXPECT_EQ(st.st_gid, 0);
158
159 /* On the underlying, non-idmapped tmpfs it is stored as MAP_HOST. */
160 snprintf(path, sizeof(path), "%s/linked", self->dir);
161 ASSERT_EQ(stat(path, &st), 0);
162 EXPECT_EQ(st.st_uid, MAP_HOST);
163 EXPECT_EQ(st.st_gid, MAP_HOST);
164
165 EXPECT_EQ(close(mfd), 0);
166}
167
168TEST_HARNESS_MAIN