Skip to content

Commit 20c2474

Browse files
committed
Merge tag 'vfs-6.12-rc2.fixes.2' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull vfs fixes from Christian Brauner: "vfs: - Ensure that iter_folioq_get_pages() advances to the next slot otherwise it will end up using the same folio with an out-of-bound offset. iomap: - Dont unshare delalloc extents which can't be reflinked, and thus can't be shared. - Constrain the file range passed to iomap_file_unshare() directly in iomap instead of requiring the callers to do it. netfs: - Use folioq_count instead of folioq_nr_slot to prevent an unitialized value warning in netfs_clear_buffer(). - Fix missing wakeup after issuing writes by scheduling the write collector only if all the subrequest queues are empty and thus no writes are pending. - Fix two minor documentation bugs" * tag 'vfs-6.12-rc2.fixes.2' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: iomap: constrain the file range passed to iomap_file_unshare iomap: don't bother unsharing delalloc extents netfs: Fix missing wakeup after issuing writes Documentation: add missing folio_queue entry folio_queue: fix documentation netfs: Fix a KMSAN uninit-value error in netfs_clear_buffer iov_iter: fix advancing slot in iter_folioq_get_pages()
2 parents 7ec4621 + a311a08 commit 20c2474

File tree

7 files changed

+43
-21
lines changed

7 files changed

+43
-21
lines changed

Documentation/core-api/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Library functionality that is used throughout the kernel.
3737
kref
3838
cleanup
3939
assoc_array
40+
folio_queue
4041
xarray
4142
maple_tree
4243
idr

fs/dax.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1305,11 +1305,15 @@ int dax_file_unshare(struct inode *inode, loff_t pos, loff_t len,
13051305
struct iomap_iter iter = {
13061306
.inode = inode,
13071307
.pos = pos,
1308-
.len = len,
13091308
.flags = IOMAP_WRITE | IOMAP_UNSHARE | IOMAP_DAX,
13101309
};
1310+
loff_t size = i_size_read(inode);
13111311
int ret;
13121312

1313+
if (pos < 0 || pos >= size)
1314+
return 0;
1315+
1316+
iter.len = min(len, size - pos);
13131317
while ((ret = iomap_iter(&iter, ops)) > 0)
13141318
iter.processed = dax_unshare_iter(&iter);
13151319
return ret;

fs/iomap/buffered-io.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,7 +1321,7 @@ static loff_t iomap_unshare_iter(struct iomap_iter *iter)
13211321
return length;
13221322

13231323
/*
1324-
* Don't bother with holes or unwritten extents.
1324+
* Don't bother with delalloc reservations, holes or unwritten extents.
13251325
*
13261326
* Note that we use srcmap directly instead of iomap_iter_srcmap as
13271327
* unsharing requires providing a separate source map, and the presence
@@ -1330,6 +1330,7 @@ static loff_t iomap_unshare_iter(struct iomap_iter *iter)
13301330
* fork for XFS.
13311331
*/
13321332
if (iter->srcmap.type == IOMAP_HOLE ||
1333+
iter->srcmap.type == IOMAP_DELALLOC ||
13331334
iter->srcmap.type == IOMAP_UNWRITTEN)
13341335
return length;
13351336

@@ -1374,11 +1375,15 @@ iomap_file_unshare(struct inode *inode, loff_t pos, loff_t len,
13741375
struct iomap_iter iter = {
13751376
.inode = inode,
13761377
.pos = pos,
1377-
.len = len,
13781378
.flags = IOMAP_WRITE | IOMAP_UNSHARE,
13791379
};
1380+
loff_t size = i_size_read(inode);
13801381
int ret;
13811382

1383+
if (pos < 0 || pos >= size)
1384+
return 0;
1385+
1386+
iter.len = min(len, size - pos);
13821387
while ((ret = iomap_iter(&iter, ops)) > 0)
13831388
iter.processed = iomap_unshare_iter(&iter);
13841389
return ret;

fs/netfs/misc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ void netfs_clear_buffer(struct netfs_io_request *rreq)
102102

103103
while ((p = rreq->buffer)) {
104104
rreq->buffer = p->next;
105-
for (int slot = 0; slot < folioq_nr_slots(p); slot++) {
105+
for (int slot = 0; slot < folioq_count(p); slot++) {
106106
struct folio *folio = folioq_folio(p, slot);
107107
if (!folio)
108108
continue;

fs/netfs/write_issue.c

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,30 @@ static int netfs_write_folio(struct netfs_io_request *wreq,
508508
return 0;
509509
}
510510

511+
/*
512+
* End the issuing of writes, letting the collector know we're done.
513+
*/
514+
static void netfs_end_issue_write(struct netfs_io_request *wreq)
515+
{
516+
bool needs_poke = true;
517+
518+
smp_wmb(); /* Write subreq lists before ALL_QUEUED. */
519+
set_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags);
520+
521+
for (int s = 0; s < NR_IO_STREAMS; s++) {
522+
struct netfs_io_stream *stream = &wreq->io_streams[s];
523+
524+
if (!stream->active)
525+
continue;
526+
if (!list_empty(&stream->subrequests))
527+
needs_poke = false;
528+
netfs_issue_write(wreq, stream);
529+
}
530+
531+
if (needs_poke)
532+
netfs_wake_write_collector(wreq, false);
533+
}
534+
511535
/*
512536
* Write some of the pending data back to the server
513537
*/
@@ -559,10 +583,7 @@ int netfs_writepages(struct address_space *mapping,
559583
break;
560584
} while ((folio = writeback_iter(mapping, wbc, folio, &error)));
561585

562-
for (int s = 0; s < NR_IO_STREAMS; s++)
563-
netfs_issue_write(wreq, &wreq->io_streams[s]);
564-
smp_wmb(); /* Write lists before ALL_QUEUED. */
565-
set_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags);
586+
netfs_end_issue_write(wreq);
566587

567588
mutex_unlock(&ictx->wb_lock);
568589

@@ -650,10 +671,7 @@ int netfs_end_writethrough(struct netfs_io_request *wreq, struct writeback_contr
650671
if (writethrough_cache)
651672
netfs_write_folio(wreq, wbc, writethrough_cache);
652673

653-
netfs_issue_write(wreq, &wreq->io_streams[0]);
654-
netfs_issue_write(wreq, &wreq->io_streams[1]);
655-
smp_wmb(); /* Write lists before ALL_QUEUED. */
656-
set_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags);
674+
netfs_end_issue_write(wreq);
657675

658676
mutex_unlock(&ictx->wb_lock);
659677

@@ -699,13 +717,7 @@ int netfs_unbuffered_write(struct netfs_io_request *wreq, bool may_wait, size_t
699717
break;
700718
}
701719

702-
netfs_issue_write(wreq, upload);
703-
704-
smp_wmb(); /* Write lists before ALL_QUEUED. */
705-
set_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags);
706-
if (list_empty(&upload->subrequests))
707-
netfs_wake_write_collector(wreq, false);
708-
720+
netfs_end_issue_write(wreq);
709721
_leave(" = %d", error);
710722
return error;
711723
}

include/linux/folio_queue.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ static inline unsigned int folioq_count(struct folio_queue *folioq)
8181
}
8282

8383
/**
84-
* folioq_count: Query if a folio queue segment is full
84+
* folioq_full: Query if a folio queue segment is full
8585
* @folioq: The segment to query
8686
*
8787
* Query if a folio queue segment is fully occupied. Note that this does not

lib/iov_iter.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1033,7 +1033,7 @@ static ssize_t iter_folioq_get_pages(struct iov_iter *iter,
10331033
if (maxpages == 0 || extracted >= maxsize)
10341034
break;
10351035

1036-
if (offset >= fsize) {
1036+
if (iov_offset >= fsize) {
10371037
iov_offset = 0;
10381038
slot++;
10391039
if (slot == folioq_nr_slots(folioq) && folioq->next) {

0 commit comments

Comments
 (0)