Skip to content

Commit 8dcf44f

Browse files
committed
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()
2 parents 56be9aa + a4b2923 commit 8dcf44f

File tree

7 files changed

+65
-46
lines changed

7 files changed

+65
-46
lines changed

fs/cachefiles/interface.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,8 @@ static void cachefiles_commit_object(struct cachefiles_object *object,
327327
static void cachefiles_clean_up_object(struct cachefiles_object *object,
328328
struct cachefiles_cache *cache)
329329
{
330+
struct file *file;
331+
330332
if (test_bit(FSCACHE_COOKIE_RETIRED, &object->cookie->flags)) {
331333
if (!test_bit(CACHEFILES_OBJECT_USING_TMPFILE, &object->flags)) {
332334
cachefiles_see_object(object, cachefiles_obj_see_clean_delete);
@@ -342,10 +344,14 @@ static void cachefiles_clean_up_object(struct cachefiles_object *object,
342344
}
343345

344346
cachefiles_unmark_inode_in_use(object, object->file);
345-
if (object->file) {
346-
fput(object->file);
347-
object->file = NULL;
348-
}
347+
348+
spin_lock(&object->lock);
349+
file = object->file;
350+
object->file = NULL;
351+
spin_unlock(&object->lock);
352+
353+
if (file)
354+
fput(file);
349355
}
350356

351357
/*

fs/cachefiles/namei.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -691,11 +691,6 @@ bool cachefiles_commit_tmpfile(struct cachefiles_cache *cache,
691691
}
692692

693693
if (!d_is_negative(dentry)) {
694-
if (d_backing_inode(dentry) == file_inode(object->file)) {
695-
success = true;
696-
goto out_dput;
697-
}
698-
699694
ret = cachefiles_unlink(volume->cache, object, fan, dentry,
700695
FSCACHE_OBJECT_IS_STALE);
701696
if (ret < 0)

fs/cachefiles/ondemand.c

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,39 +60,59 @@ static ssize_t cachefiles_ondemand_fd_write_iter(struct kiocb *kiocb,
6060
{
6161
struct cachefiles_object *object = kiocb->ki_filp->private_data;
6262
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;
6565
loff_t pos = kiocb->ki_pos;
6666
const struct cred *saved_cred;
6767
int ret;
6868

69-
if (!file)
69+
spin_lock(&object->lock);
70+
file = object->file;
71+
if (!file) {
72+
spin_unlock(&object->lock);
7073
return -ENOBUFS;
74+
}
75+
get_file(file);
76+
spin_unlock(&object->lock);
7177

7278
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);
7480
cachefiles_end_secure(cache, saved_cred);
7581
if (ret < 0)
76-
return ret;
82+
goto out;
7783

7884
trace_cachefiles_ondemand_fd_write(object, file_inode(file), pos, len);
7985
ret = __cachefiles_write(object, file, pos, iter, NULL, NULL);
80-
if (!ret)
86+
if (!ret) {
8187
ret = len;
88+
kiocb->ki_pos += ret;
89+
}
8290

91+
out:
92+
fput(file);
8393
return ret;
8494
}
8595

8696
static loff_t cachefiles_ondemand_fd_llseek(struct file *filp, loff_t pos,
8797
int whence)
8898
{
8999
struct cachefiles_object *object = filp->private_data;
90-
struct file *file = object->file;
100+
struct file *file;
101+
loff_t ret;
91102

92-
if (!file)
103+
spin_lock(&object->lock);
104+
file = object->file;
105+
if (!file) {
106+
spin_unlock(&object->lock);
93107
return -ENOBUFS;
108+
}
109+
get_file(file);
110+
spin_unlock(&object->lock);
94111

95-
return vfs_llseek(file, pos, whence);
112+
ret = vfs_llseek(file, pos, whence);
113+
fput(file);
114+
115+
return ret;
96116
}
97117

98118
static long cachefiles_ondemand_fd_ioctl(struct file *filp, unsigned int ioctl,

fs/netfs/buffered_read.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,7 @@ static bool netfs_skip_folio_read(struct folio *folio, loff_t pos, size_t len,
627627
if (unlikely(always_fill)) {
628628
if (pos - offset + len <= i_size)
629629
return false; /* Page entirely before EOF */
630-
zero_user_segment(&folio->page, 0, plen);
630+
folio_zero_segment(folio, 0, plen);
631631
folio_mark_uptodate(folio);
632632
return true;
633633
}
@@ -646,7 +646,7 @@ static bool netfs_skip_folio_read(struct folio *folio, loff_t pos, size_t len,
646646

647647
return false;
648648
zero_out:
649-
zero_user_segments(&folio->page, 0, offset, offset + len, plen);
649+
folio_zero_segments(folio, 0, offset, offset + len, plen);
650650
return true;
651651
}
652652

@@ -713,7 +713,7 @@ int netfs_write_begin(struct netfs_inode *ctx,
713713
if (folio_test_uptodate(folio))
714714
goto have_folio;
715715

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
717717
* within the cache granule containing the EOF, in which case we need
718718
* to preload the granule.
719719
*/
@@ -773,7 +773,7 @@ int netfs_write_begin(struct netfs_inode *ctx,
773773
EXPORT_SYMBOL(netfs_write_begin);
774774

775775
/*
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.
777777
*/
778778
int netfs_prefetch_for_write(struct file *file, struct folio *folio,
779779
size_t offset, size_t len)

fs/netfs/buffered_write.c

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,13 @@ static void netfs_update_i_size(struct netfs_inode *ctx, struct inode *inode,
8383
* netfs_perform_write - Copy data into the pagecache.
8484
* @iocb: The operation parameters
8585
* @iter: The source buffer
86-
* @netfs_group: Grouping for dirty pages (eg. ceph snaps).
86+
* @netfs_group: Grouping for dirty folios (eg. ceph snaps).
8787
*
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.
8989
* The caller must hold appropriate inode locks.
9090
*
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
9393
* netfs-specific grouping such that data from an old group gets flushed before
9494
* a new one is started.
9595
*/
@@ -223,11 +223,11 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter,
223223
* we try to read it.
224224
*/
225225
if (fpos >= ctx->zero_point) {
226-
zero_user_segment(&folio->page, 0, offset);
226+
folio_zero_segment(folio, 0, offset);
227227
copied = copy_folio_from_iter_atomic(folio, offset, part, iter);
228228
if (unlikely(copied == 0))
229229
goto copy_failed;
230-
zero_user_segment(&folio->page, offset + copied, flen);
230+
folio_zero_segment(folio, offset + copied, flen);
231231
__netfs_set_group(folio, netfs_group);
232232
folio_mark_uptodate(folio);
233233
trace_netfs_folio(folio, netfs_modify_and_clear);
@@ -407,7 +407,7 @@ EXPORT_SYMBOL(netfs_perform_write);
407407
* netfs_buffered_write_iter_locked - write data to a file
408408
* @iocb: IO state structure (file, offset, etc.)
409409
* @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).
411411
*
412412
* This function does all the work needed for actually writing data to a
413413
* file. It does all basic checks, removes SUID from the file, updates
@@ -491,7 +491,9 @@ EXPORT_SYMBOL(netfs_file_write_iter);
491491

492492
/*
493493
* 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.
495497
*/
496498
vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_group)
497499
{
@@ -501,7 +503,7 @@ vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_gr
501503
struct address_space *mapping = file->f_mapping;
502504
struct inode *inode = file_inode(file);
503505
struct netfs_inode *ictx = netfs_inode(inode);
504-
vm_fault_t ret = VM_FAULT_RETRY;
506+
vm_fault_t ret = VM_FAULT_NOPAGE;
505507
int err;
506508

507509
_enter("%lx", folio->index);
@@ -510,21 +512,15 @@ vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_gr
510512

511513
if (folio_lock_killable(folio) < 0)
512514
goto out;
513-
if (folio->mapping != mapping) {
514-
folio_unlock(folio);
515-
ret = VM_FAULT_NOPAGE;
516-
goto out;
517-
}
518-
519-
if (folio_wait_writeback_killable(folio)) {
520-
ret = VM_FAULT_LOCKED;
521-
goto out;
522-
}
515+
if (folio->mapping != mapping)
516+
goto unlock;
517+
if (folio_wait_writeback_killable(folio) < 0)
518+
goto unlock;
523519

524520
/* Can we see a streaming write here? */
525521
if (WARN_ON(!folio_test_uptodate(folio))) {
526-
ret = VM_FAULT_SIGBUS | VM_FAULT_LOCKED;
527-
goto out;
522+
ret = VM_FAULT_SIGBUS;
523+
goto unlock;
528524
}
529525

530526
group = netfs_folio_group(folio);
@@ -559,5 +555,8 @@ vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_gr
559555
out:
560556
sb_end_pagefault(inode->i_sb);
561557
return ret;
558+
unlock:
559+
folio_unlock(folio);
560+
goto out;
562561
}
563562
EXPORT_SYMBOL(netfs_page_mkwrite);

fs/netfs/fscache_volume.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,7 @@ void fscache_create_volume(struct fscache_volume *volume, bool wait)
322322
}
323323
return;
324324
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);
327326
}
328327

329328
/*

include/trace/events/netfs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ TRACE_EVENT(netfs_folio,
450450
struct address_space *__m = READ_ONCE(folio->mapping);
451451
__entry->ino = __m ? __m->host->i_ino : 0;
452452
__entry->why = why;
453-
__entry->index = folio_index(folio);
453+
__entry->index = folio->index;
454454
__entry->nr = folio_nr_pages(folio);
455455
),
456456

0 commit comments

Comments
 (0)