Skip to content

Commit 1d5911d

Browse files
committed
Merge tag 'netfs-lib-20240109' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs into vfs.netfs
Pull netfs updates from David Howells: A few follow-up fixes for the netfs work for this cycle. * tag 'netfs-lib-20240109' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs: netfs: Fix wrong #ifdef hiding wait cachefiles: Fix signed/unsigned mixup netfs: Fix the loop that unmarks folios after writing to the cache netfs: Fix interaction between write-streaming and cachefiles culling netfs: Count DIO writes netfs: Mark netfs_unbuffered_write_iter_locked() static Tested-by: Marc Dionne <marc.dionne@auristor.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Christian Brauner <brauner@kernel.org>
2 parents d271c4b + e2bdb52 commit 1d5911d

File tree

9 files changed

+56
-30
lines changed

9 files changed

+56
-30
lines changed

fs/cachefiles/io.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -522,18 +522,18 @@ int __cachefiles_prepare_write(struct cachefiles_object *object,
522522
bool no_space_allocated_yet)
523523
{
524524
struct cachefiles_cache *cache = object->volume->cache;
525-
unsigned long long start = *_start, pos;
525+
loff_t start = *_start, pos;
526526
size_t len = *_len;
527527
int ret;
528528

529529
/* Round to DIO size */
530530
start = round_down(*_start, PAGE_SIZE);
531-
if (start != *_start) {
532-
kleave(" = -ENOBUFS [down]");
533-
return -ENOBUFS;
534-
}
535-
if (*_len > upper_len) {
536-
kleave(" = -ENOBUFS [up]");
531+
if (start != *_start || *_len > upper_len) {
532+
/* Probably asked to cache a streaming write written into the
533+
* pagecache when the cookie was temporarily out of service to
534+
* culling.
535+
*/
536+
fscache_count_dio_misfit();
537537
return -ENOBUFS;
538538
}
539539

@@ -556,7 +556,7 @@ int __cachefiles_prepare_write(struct cachefiles_object *object,
556556
cachefiles_trace_seek_error);
557557
return pos;
558558
}
559-
if (pos >= start + *_len)
559+
if ((u64)pos >= (u64)start + *_len)
560560
goto check_space; /* Unallocated region */
561561

562562
/* We have a block that's at least partially filled - if we're low on
@@ -575,7 +575,7 @@ int __cachefiles_prepare_write(struct cachefiles_object *object,
575575
cachefiles_trace_seek_error);
576576
return pos;
577577
}
578-
if (pos >= start + *_len)
578+
if ((u64)pos >= (u64)start + *_len)
579579
return 0; /* Fully allocated */
580580

581581
/* Partially allocated, but insufficient space: cull. */

fs/netfs/buffered_write.c

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,19 @@ static enum netfs_how_to_modify netfs_how_to_modify(struct netfs_inode *ctx,
8080
return NETFS_WHOLE_FOLIO_MODIFY;
8181

8282
if (file->f_mode & FMODE_READ)
83-
return NETFS_JUST_PREFETCH;
84-
85-
if (netfs_is_cache_enabled(ctx))
86-
return NETFS_JUST_PREFETCH;
83+
goto no_write_streaming;
84+
if (test_bit(NETFS_ICTX_NO_WRITE_STREAMING, &ctx->flags))
85+
goto no_write_streaming;
86+
87+
if (netfs_is_cache_enabled(ctx)) {
88+
/* We don't want to get a streaming write on a file that loses
89+
* caching service temporarily because the backing store got
90+
* culled.
91+
*/
92+
if (!test_bit(NETFS_ICTX_NO_WRITE_STREAMING, &ctx->flags))
93+
set_bit(NETFS_ICTX_NO_WRITE_STREAMING, &ctx->flags);
94+
goto no_write_streaming;
95+
}
8796

8897
if (!finfo)
8998
return NETFS_STREAMING_WRITE;
@@ -95,6 +104,13 @@ static enum netfs_how_to_modify netfs_how_to_modify(struct netfs_inode *ctx,
95104
if (offset == finfo->dirty_offset + finfo->dirty_len)
96105
return NETFS_STREAMING_WRITE_CONT;
97106
return NETFS_FLUSH_CONTENT;
107+
108+
no_write_streaming:
109+
if (finfo) {
110+
netfs_stat(&netfs_n_wh_wstream_conflict);
111+
return NETFS_FLUSH_CONTENT;
112+
}
113+
return NETFS_JUST_PREFETCH;
98114
}
99115

100116
/*
@@ -682,6 +698,7 @@ static void netfs_pages_written_back(struct netfs_io_request *wreq)
682698
end_wb:
683699
if (folio_test_fscache(folio))
684700
folio_end_fscache(folio);
701+
xas_advance(&xas, folio_next_index(folio) - 1);
685702
folio_end_writeback(folio);
686703
}
687704

@@ -1059,7 +1076,7 @@ static ssize_t netfs_writepages_begin(struct address_space *mapping,
10591076
folio_unlock(folio);
10601077
if (wbc->sync_mode != WB_SYNC_NONE) {
10611078
folio_wait_writeback(folio);
1062-
#ifdef CONFIG_NETFS_FSCACHE
1079+
#ifdef CONFIG_FSCACHE
10631080
folio_wait_fscache(folio);
10641081
#endif
10651082
goto lock_again;

fs/netfs/direct_write.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ static void netfs_cleanup_dio_write(struct netfs_io_request *wreq)
2727
* Perform an unbuffered write where we may have to do an RMW operation on an
2828
* encrypted file. This can also be used for direct I/O writes.
2929
*/
30-
ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov_iter *iter,
31-
struct netfs_group *netfs_group)
30+
static ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov_iter *iter,
31+
struct netfs_group *netfs_group)
3232
{
3333
struct netfs_io_request *wreq;
3434
unsigned long long start = iocb->ki_pos;
@@ -140,6 +140,7 @@ ssize_t netfs_unbuffered_write_iter(struct kiocb *iocb, struct iov_iter *from)
140140
_enter("%llx,%zx,%llx", iocb->ki_pos, iov_iter_count(from), i_size_read(inode));
141141

142142
trace_netfs_write_iter(iocb, from);
143+
netfs_stat(&netfs_n_rh_dio_write);
143144

144145
ret = netfs_start_io_direct(inode);
145146
if (ret < 0)

fs/netfs/fscache_stats.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,15 @@ atomic_t fscache_n_no_create_space;
4848
EXPORT_SYMBOL(fscache_n_no_create_space);
4949
atomic_t fscache_n_culled;
5050
EXPORT_SYMBOL(fscache_n_culled);
51+
atomic_t fscache_n_dio_misfit;
52+
EXPORT_SYMBOL(fscache_n_dio_misfit);
5153

5254
/*
5355
* display the general statistics
5456
*/
5557
int fscache_stats_show(struct seq_file *m)
5658
{
57-
seq_puts(m, "FS-Cache statistics\n");
59+
seq_puts(m, "-- FS-Cache statistics --\n");
5860
seq_printf(m, "Cookies: n=%d v=%d vcol=%u voom=%u\n",
5961
atomic_read(&fscache_n_cookies),
6062
atomic_read(&fscache_n_volumes),
@@ -93,8 +95,9 @@ int fscache_stats_show(struct seq_file *m)
9395
atomic_read(&fscache_n_no_create_space),
9496
atomic_read(&fscache_n_culled));
9597

96-
seq_printf(m, "IO : rd=%u wr=%u\n",
98+
seq_printf(m, "IO : rd=%u wr=%u mis=%u\n",
9799
atomic_read(&fscache_n_read),
98-
atomic_read(&fscache_n_write));
100+
atomic_read(&fscache_n_write),
101+
atomic_read(&fscache_n_dio_misfit));
99102
return 0;
100103
}

fs/netfs/internal.h

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,6 @@ void netfs_rreq_unlock_folios(struct netfs_io_request *rreq);
2626
int netfs_prefetch_for_write(struct file *file, struct folio *folio,
2727
size_t offset, size_t len);
2828

29-
/*
30-
* direct_write.c
31-
*/
32-
ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov_iter *iter,
33-
struct netfs_group *netfs_group);
34-
3529
/*
3630
* io.c
3731
*/
@@ -110,6 +104,7 @@ int netfs_end_writethrough(struct netfs_io_request *wreq, struct kiocb *iocb);
110104
*/
111105
#ifdef CONFIG_NETFS_STATS
112106
extern atomic_t netfs_n_rh_dio_read;
107+
extern atomic_t netfs_n_rh_dio_write;
113108
extern atomic_t netfs_n_rh_readahead;
114109
extern atomic_t netfs_n_rh_readpage;
115110
extern atomic_t netfs_n_rh_rreq;
@@ -128,6 +123,7 @@ extern atomic_t netfs_n_rh_write_begin;
128123
extern atomic_t netfs_n_rh_write_done;
129124
extern atomic_t netfs_n_rh_write_failed;
130125
extern atomic_t netfs_n_rh_write_zskip;
126+
extern atomic_t netfs_n_wh_wstream_conflict;
131127
extern atomic_t netfs_n_wh_upload;
132128
extern atomic_t netfs_n_wh_upload_done;
133129
extern atomic_t netfs_n_wh_upload_failed;

fs/netfs/io.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ static void netfs_rreq_unmark_after_write(struct netfs_io_request *rreq,
126126
*/
127127
if (have_unlocked && folio_index(folio) <= unlocked)
128128
continue;
129-
unlocked = folio_index(folio);
129+
unlocked = folio_next_index(folio) - 1;
130130
trace_netfs_folio(folio, netfs_folio_trace_end_copy);
131131
folio_end_fscache(folio);
132132
have_unlocked = true;

fs/netfs/stats.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "internal.h"
1111

1212
atomic_t netfs_n_rh_dio_read;
13+
atomic_t netfs_n_rh_dio_write;
1314
atomic_t netfs_n_rh_readahead;
1415
atomic_t netfs_n_rh_readpage;
1516
atomic_t netfs_n_rh_rreq;
@@ -28,6 +29,7 @@ atomic_t netfs_n_rh_write_begin;
2829
atomic_t netfs_n_rh_write_done;
2930
atomic_t netfs_n_rh_write_failed;
3031
atomic_t netfs_n_rh_write_zskip;
32+
atomic_t netfs_n_wh_wstream_conflict;
3133
atomic_t netfs_n_wh_upload;
3234
atomic_t netfs_n_wh_upload_done;
3335
atomic_t netfs_n_wh_upload_failed;
@@ -37,14 +39,13 @@ atomic_t netfs_n_wh_write_failed;
3739

3840
int netfs_stats_show(struct seq_file *m, void *v)
3941
{
40-
seq_printf(m, "Netfs : DR=%u RA=%u RP=%u WB=%u WBZ=%u rr=%u sr=%u\n",
42+
seq_printf(m, "Netfs : DR=%u DW=%u RA=%u RP=%u WB=%u WBZ=%u\n",
4143
atomic_read(&netfs_n_rh_dio_read),
44+
atomic_read(&netfs_n_rh_dio_write),
4245
atomic_read(&netfs_n_rh_readahead),
4346
atomic_read(&netfs_n_rh_readpage),
4447
atomic_read(&netfs_n_rh_write_begin),
45-
atomic_read(&netfs_n_rh_write_zskip),
46-
atomic_read(&netfs_n_rh_rreq),
47-
atomic_read(&netfs_n_rh_sreq));
48+
atomic_read(&netfs_n_rh_write_zskip));
4849
seq_printf(m, "Netfs : ZR=%u sh=%u sk=%u\n",
4950
atomic_read(&netfs_n_rh_zero),
5051
atomic_read(&netfs_n_rh_short_read),
@@ -66,6 +67,10 @@ int netfs_stats_show(struct seq_file *m, void *v)
6667
atomic_read(&netfs_n_wh_write),
6768
atomic_read(&netfs_n_wh_write_done),
6869
atomic_read(&netfs_n_wh_write_failed));
70+
seq_printf(m, "Netfs : rr=%u sr=%u wsc=%u\n",
71+
atomic_read(&netfs_n_rh_rreq),
72+
atomic_read(&netfs_n_rh_sreq),
73+
atomic_read(&netfs_n_wh_wstream_conflict));
6974
return fscache_stats_show(m);
7075
}
7176
EXPORT_SYMBOL(netfs_stats_show);

include/linux/fscache-cache.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,17 +189,20 @@ extern atomic_t fscache_n_write;
189189
extern atomic_t fscache_n_no_write_space;
190190
extern atomic_t fscache_n_no_create_space;
191191
extern atomic_t fscache_n_culled;
192+
extern atomic_t fscache_n_dio_misfit;
192193
#define fscache_count_read() atomic_inc(&fscache_n_read)
193194
#define fscache_count_write() atomic_inc(&fscache_n_write)
194195
#define fscache_count_no_write_space() atomic_inc(&fscache_n_no_write_space)
195196
#define fscache_count_no_create_space() atomic_inc(&fscache_n_no_create_space)
196197
#define fscache_count_culled() atomic_inc(&fscache_n_culled)
198+
#define fscache_count_dio_misfit() atomic_inc(&fscache_n_dio_misfit)
197199
#else
198200
#define fscache_count_read() do {} while(0)
199201
#define fscache_count_write() do {} while(0)
200202
#define fscache_count_no_write_space() do {} while(0)
201203
#define fscache_count_no_create_space() do {} while(0)
202204
#define fscache_count_culled() do {} while(0)
205+
#define fscache_count_dio_misfit() do {} while(0)
203206
#endif
204207

205208
#endif /* _LINUX_FSCACHE_CACHE_H */

include/linux/netfs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ struct netfs_inode {
142142
#define NETFS_ICTX_ODIRECT 0 /* The file has DIO in progress */
143143
#define NETFS_ICTX_UNBUFFERED 1 /* I/O should not use the pagecache */
144144
#define NETFS_ICTX_WRITETHROUGH 2 /* Write-through caching */
145+
#define NETFS_ICTX_NO_WRITE_STREAMING 3 /* Don't engage in write-streaming */
145146
};
146147

147148
/*

0 commit comments

Comments
 (0)