Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'vfs-6.13.netfs' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull netfs updates from Christian Brauner:
"Various fixes for the netfs library and related infrastructure:

cachefiles:

- Fix a dentry leak in cachefiles_open_file()

- Fix incorrect length return value in
cachefiles_ondemand_fd_write_iter()

- Fix missing pos updates in cachefiles_ondemand_fd_write_iter()

- Clean up in cachefiles_commit_tmpfile()

- Fix NULL pointer dereference in object->file

- Add a memory barrier for FSCACHE_VOLUME_CREATING

netfs:

- Remove call to folio_index()

- Fix a few minor bugs in netfs_page_mkwrite()

- Remove unnecessary references to pages"

* tag 'vfs-6.13.netfs' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
netfs/fscache: Add a memory barrier for FSCACHE_VOLUME_CREATING
cachefiles: Fix NULL pointer dereference in object->file
cachefiles: Clean up in cachefiles_commit_tmpfile()
cachefiles: Fix missing pos updates in cachefiles_ondemand_fd_write_iter()
cachefiles: Fix incorrect length return value in cachefiles_ondemand_fd_write_iter()
netfs: Remove unnecessary references to pages
netfs: Fix a few minor bugs in netfs_page_mkwrite()
netfs: Remove call to folio_index()

+65 -46
+10 -4
fs/cachefiles/interface.c
··· 327 327 static void cachefiles_clean_up_object(struct cachefiles_object *object, 328 328 struct cachefiles_cache *cache) 329 329 { 330 + struct file *file; 331 + 330 332 if (test_bit(FSCACHE_COOKIE_RETIRED, &object->cookie->flags)) { 331 333 if (!test_bit(CACHEFILES_OBJECT_USING_TMPFILE, &object->flags)) { 332 334 cachefiles_see_object(object, cachefiles_obj_see_clean_delete); ··· 344 342 } 345 343 346 344 cachefiles_unmark_inode_in_use(object, object->file); 347 - if (object->file) { 348 - fput(object->file); 349 - object->file = NULL; 350 - } 345 + 346 + spin_lock(&object->lock); 347 + file = object->file; 348 + object->file = NULL; 349 + spin_unlock(&object->lock); 350 + 351 + if (file) 352 + fput(file); 351 353 } 352 354 353 355 /*
-5
fs/cachefiles/namei.c
··· 691 691 } 692 692 693 693 if (!d_is_negative(dentry)) { 694 - if (d_backing_inode(dentry) == file_inode(object->file)) { 695 - success = true; 696 - goto out_dput; 697 - } 698 - 699 694 ret = cachefiles_unlink(volume->cache, object, fan, dentry, 700 695 FSCACHE_OBJECT_IS_STALE); 701 696 if (ret < 0)
+29 -9
fs/cachefiles/ondemand.c
··· 60 60 { 61 61 struct cachefiles_object *object = kiocb->ki_filp->private_data; 62 62 struct cachefiles_cache *cache = object->volume->cache; 63 - struct file *file = object->file; 64 - size_t len = iter->count; 63 + struct file *file; 64 + size_t len = iter->count, aligned_len = len; 65 65 loff_t pos = kiocb->ki_pos; 66 66 const struct cred *saved_cred; 67 67 int ret; 68 68 69 - if (!file) 69 + spin_lock(&object->lock); 70 + file = object->file; 71 + if (!file) { 72 + spin_unlock(&object->lock); 70 73 return -ENOBUFS; 74 + } 75 + get_file(file); 76 + spin_unlock(&object->lock); 71 77 72 78 cachefiles_begin_secure(cache, &saved_cred); 73 - ret = __cachefiles_prepare_write(object, file, &pos, &len, len, true); 79 + ret = __cachefiles_prepare_write(object, file, &pos, &aligned_len, len, true); 74 80 cachefiles_end_secure(cache, saved_cred); 75 81 if (ret < 0) 76 - return ret; 82 + goto out; 77 83 78 84 trace_cachefiles_ondemand_fd_write(object, file_inode(file), pos, len); 79 85 ret = __cachefiles_write(object, file, pos, iter, NULL, NULL); 80 - if (!ret) 86 + if (!ret) { 81 87 ret = len; 88 + kiocb->ki_pos += ret; 89 + } 82 90 91 + out: 92 + fput(file); 83 93 return ret; 84 94 } 85 95 ··· 97 87 int whence) 98 88 { 99 89 struct cachefiles_object *object = filp->private_data; 100 - struct file *file = object->file; 90 + struct file *file; 91 + loff_t ret; 101 92 102 - if (!file) 93 + spin_lock(&object->lock); 94 + file = object->file; 95 + if (!file) { 96 + spin_unlock(&object->lock); 103 97 return -ENOBUFS; 98 + } 99 + get_file(file); 100 + spin_unlock(&object->lock); 104 101 105 - return vfs_llseek(file, pos, whence); 102 + ret = vfs_llseek(file, pos, whence); 103 + fput(file); 104 + 105 + return ret; 106 106 } 107 107 108 108 static long cachefiles_ondemand_fd_ioctl(struct file *filp, unsigned int ioctl,
+4 -4
fs/netfs/buffered_read.c
··· 627 627 if (unlikely(always_fill)) { 628 628 if (pos - offset + len <= i_size) 629 629 return false; /* Page entirely before EOF */ 630 - zero_user_segment(&folio->page, 0, plen); 630 + folio_zero_segment(folio, 0, plen); 631 631 folio_mark_uptodate(folio); 632 632 return true; 633 633 } ··· 646 646 647 647 return false; 648 648 zero_out: 649 - zero_user_segments(&folio->page, 0, offset, offset + len, plen); 649 + folio_zero_segments(folio, 0, offset, offset + len, plen); 650 650 return true; 651 651 } 652 652 ··· 713 713 if (folio_test_uptodate(folio)) 714 714 goto have_folio; 715 715 716 - /* If the page is beyond the EOF, we want to clear it - unless it's 716 + /* If the folio is beyond the EOF, we want to clear it - unless it's 717 717 * within the cache granule containing the EOF, in which case we need 718 718 * to preload the granule. 719 719 */ ··· 773 773 EXPORT_SYMBOL(netfs_write_begin); 774 774 775 775 /* 776 - * Preload the data into a page we're proposing to write into. 776 + * Preload the data into a folio we're proposing to write into. 777 777 */ 778 778 int netfs_prefetch_for_write(struct file *file, struct folio *folio, 779 779 size_t offset, size_t len)
+20 -21
fs/netfs/buffered_write.c
··· 83 83 * netfs_perform_write - Copy data into the pagecache. 84 84 * @iocb: The operation parameters 85 85 * @iter: The source buffer 86 - * @netfs_group: Grouping for dirty pages (eg. ceph snaps). 86 + * @netfs_group: Grouping for dirty folios (eg. ceph snaps). 87 87 * 88 - * Copy data into pagecache pages attached to the inode specified by @iocb. 88 + * Copy data into pagecache folios attached to the inode specified by @iocb. 89 89 * The caller must hold appropriate inode locks. 90 90 * 91 - * Dirty pages are tagged with a netfs_folio struct if they're not up to date 92 - * to indicate the range modified. Dirty pages may also be tagged with a 91 + * Dirty folios are tagged with a netfs_folio struct if they're not up to date 92 + * to indicate the range modified. Dirty folios may also be tagged with a 93 93 * netfs-specific grouping such that data from an old group gets flushed before 94 94 * a new one is started. 95 95 */ ··· 223 223 * we try to read it. 224 224 */ 225 225 if (fpos >= ctx->zero_point) { 226 - zero_user_segment(&folio->page, 0, offset); 226 + folio_zero_segment(folio, 0, offset); 227 227 copied = copy_folio_from_iter_atomic(folio, offset, part, iter); 228 228 if (unlikely(copied == 0)) 229 229 goto copy_failed; 230 - zero_user_segment(&folio->page, offset + copied, flen); 230 + folio_zero_segment(folio, offset + copied, flen); 231 231 __netfs_set_group(folio, netfs_group); 232 232 folio_mark_uptodate(folio); 233 233 trace_netfs_folio(folio, netfs_modify_and_clear); ··· 407 407 * netfs_buffered_write_iter_locked - write data to a file 408 408 * @iocb: IO state structure (file, offset, etc.) 409 409 * @from: iov_iter with data to write 410 - * @netfs_group: Grouping for dirty pages (eg. ceph snaps). 410 + * @netfs_group: Grouping for dirty folios (eg. ceph snaps). 411 411 * 412 412 * This function does all the work needed for actually writing data to a 413 413 * file. It does all basic checks, removes SUID from the file, updates ··· 491 491 492 492 /* 493 493 * Notification that a previously read-only page is about to become writable. 494 - * Note that the caller indicates a single page of a multipage folio. 494 + * The caller indicates the precise page that needs to be written to, but 495 + * we only track group on a per-folio basis, so we block more often than 496 + * we might otherwise. 495 497 */ 496 498 vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_group) 497 499 { ··· 503 501 struct address_space *mapping = file->f_mapping; 504 502 struct inode *inode = file_inode(file); 505 503 struct netfs_inode *ictx = netfs_inode(inode); 506 - vm_fault_t ret = VM_FAULT_RETRY; 504 + vm_fault_t ret = VM_FAULT_NOPAGE; 507 505 int err; 508 506 509 507 _enter("%lx", folio->index); ··· 512 510 513 511 if (folio_lock_killable(folio) < 0) 514 512 goto out; 515 - if (folio->mapping != mapping) { 516 - folio_unlock(folio); 517 - ret = VM_FAULT_NOPAGE; 518 - goto out; 519 - } 520 - 521 - if (folio_wait_writeback_killable(folio)) { 522 - ret = VM_FAULT_LOCKED; 523 - goto out; 524 - } 513 + if (folio->mapping != mapping) 514 + goto unlock; 515 + if (folio_wait_writeback_killable(folio) < 0) 516 + goto unlock; 525 517 526 518 /* Can we see a streaming write here? */ 527 519 if (WARN_ON(!folio_test_uptodate(folio))) { 528 - ret = VM_FAULT_SIGBUS | VM_FAULT_LOCKED; 529 - goto out; 520 + ret = VM_FAULT_SIGBUS; 521 + goto unlock; 530 522 } 531 523 532 524 group = netfs_folio_group(folio); ··· 555 559 out: 556 560 sb_end_pagefault(inode->i_sb); 557 561 return ret; 562 + unlock: 563 + folio_unlock(folio); 564 + goto out; 558 565 } 559 566 EXPORT_SYMBOL(netfs_page_mkwrite);
+1 -2
fs/netfs/fscache_volume.c
··· 322 322 } 323 323 return; 324 324 no_wait: 325 - clear_bit_unlock(FSCACHE_VOLUME_CREATING, &volume->flags); 326 - wake_up_bit(&volume->flags, FSCACHE_VOLUME_CREATING); 325 + clear_and_wake_up_bit(FSCACHE_VOLUME_CREATING, &volume->flags); 327 326 } 328 327 329 328 /*
+1 -1
include/trace/events/netfs.h
··· 450 450 struct address_space *__m = READ_ONCE(folio->mapping); 451 451 __entry->ino = __m ? __m->host->i_ino : 0; 452 452 __entry->why = why; 453 - __entry->index = folio_index(folio); 453 + __entry->index = folio->index; 454 454 __entry->nr = folio_nr_pages(folio); 455 455 ), 456 456