Commit 1d5911d4 authored by Christian Brauner's avatar Christian Brauner

Merge tag 'netfs-lib-20240109' of...

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: default avatarMarc Dionne <marc.dionne@auristor.com>
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarChristian Brauner <brauner@kernel.org>
parents d271c4b4 e2bdb527
...@@ -522,18 +522,18 @@ int __cachefiles_prepare_write(struct cachefiles_object *object, ...@@ -522,18 +522,18 @@ int __cachefiles_prepare_write(struct cachefiles_object *object,
bool no_space_allocated_yet) bool no_space_allocated_yet)
{ {
struct cachefiles_cache *cache = object->volume->cache; struct cachefiles_cache *cache = object->volume->cache;
unsigned long long start = *_start, pos; loff_t start = *_start, pos;
size_t len = *_len; size_t len = *_len;
int ret; int ret;
/* Round to DIO size */ /* Round to DIO size */
start = round_down(*_start, PAGE_SIZE); start = round_down(*_start, PAGE_SIZE);
if (start != *_start) { if (start != *_start || *_len > upper_len) {
kleave(" = -ENOBUFS [down]"); /* Probably asked to cache a streaming write written into the
return -ENOBUFS; * pagecache when the cookie was temporarily out of service to
} * culling.
if (*_len > upper_len) { */
kleave(" = -ENOBUFS [up]"); fscache_count_dio_misfit();
return -ENOBUFS; return -ENOBUFS;
} }
...@@ -556,7 +556,7 @@ int __cachefiles_prepare_write(struct cachefiles_object *object, ...@@ -556,7 +556,7 @@ int __cachefiles_prepare_write(struct cachefiles_object *object,
cachefiles_trace_seek_error); cachefiles_trace_seek_error);
return pos; return pos;
} }
if (pos >= start + *_len) if ((u64)pos >= (u64)start + *_len)
goto check_space; /* Unallocated region */ goto check_space; /* Unallocated region */
/* We have a block that's at least partially filled - if we're low on /* 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, ...@@ -575,7 +575,7 @@ int __cachefiles_prepare_write(struct cachefiles_object *object,
cachefiles_trace_seek_error); cachefiles_trace_seek_error);
return pos; return pos;
} }
if (pos >= start + *_len) if ((u64)pos >= (u64)start + *_len)
return 0; /* Fully allocated */ return 0; /* Fully allocated */
/* Partially allocated, but insufficient space: cull. */ /* Partially allocated, but insufficient space: cull. */
......
...@@ -80,10 +80,19 @@ static enum netfs_how_to_modify netfs_how_to_modify(struct netfs_inode *ctx, ...@@ -80,10 +80,19 @@ static enum netfs_how_to_modify netfs_how_to_modify(struct netfs_inode *ctx,
return NETFS_WHOLE_FOLIO_MODIFY; return NETFS_WHOLE_FOLIO_MODIFY;
if (file->f_mode & FMODE_READ) if (file->f_mode & FMODE_READ)
return NETFS_JUST_PREFETCH; goto no_write_streaming;
if (test_bit(NETFS_ICTX_NO_WRITE_STREAMING, &ctx->flags))
if (netfs_is_cache_enabled(ctx)) goto no_write_streaming;
return NETFS_JUST_PREFETCH;
if (netfs_is_cache_enabled(ctx)) {
/* We don't want to get a streaming write on a file that loses
* caching service temporarily because the backing store got
* culled.
*/
if (!test_bit(NETFS_ICTX_NO_WRITE_STREAMING, &ctx->flags))
set_bit(NETFS_ICTX_NO_WRITE_STREAMING, &ctx->flags);
goto no_write_streaming;
}
if (!finfo) if (!finfo)
return NETFS_STREAMING_WRITE; return NETFS_STREAMING_WRITE;
...@@ -95,6 +104,13 @@ static enum netfs_how_to_modify netfs_how_to_modify(struct netfs_inode *ctx, ...@@ -95,6 +104,13 @@ static enum netfs_how_to_modify netfs_how_to_modify(struct netfs_inode *ctx,
if (offset == finfo->dirty_offset + finfo->dirty_len) if (offset == finfo->dirty_offset + finfo->dirty_len)
return NETFS_STREAMING_WRITE_CONT; return NETFS_STREAMING_WRITE_CONT;
return NETFS_FLUSH_CONTENT; return NETFS_FLUSH_CONTENT;
no_write_streaming:
if (finfo) {
netfs_stat(&netfs_n_wh_wstream_conflict);
return NETFS_FLUSH_CONTENT;
}
return NETFS_JUST_PREFETCH;
} }
/* /*
...@@ -682,6 +698,7 @@ static void netfs_pages_written_back(struct netfs_io_request *wreq) ...@@ -682,6 +698,7 @@ static void netfs_pages_written_back(struct netfs_io_request *wreq)
end_wb: end_wb:
if (folio_test_fscache(folio)) if (folio_test_fscache(folio))
folio_end_fscache(folio); folio_end_fscache(folio);
xas_advance(&xas, folio_next_index(folio) - 1);
folio_end_writeback(folio); folio_end_writeback(folio);
} }
...@@ -1059,7 +1076,7 @@ static ssize_t netfs_writepages_begin(struct address_space *mapping, ...@@ -1059,7 +1076,7 @@ static ssize_t netfs_writepages_begin(struct address_space *mapping,
folio_unlock(folio); folio_unlock(folio);
if (wbc->sync_mode != WB_SYNC_NONE) { if (wbc->sync_mode != WB_SYNC_NONE) {
folio_wait_writeback(folio); folio_wait_writeback(folio);
#ifdef CONFIG_NETFS_FSCACHE #ifdef CONFIG_FSCACHE
folio_wait_fscache(folio); folio_wait_fscache(folio);
#endif #endif
goto lock_again; goto lock_again;
......
...@@ -27,8 +27,8 @@ static void netfs_cleanup_dio_write(struct netfs_io_request *wreq) ...@@ -27,8 +27,8 @@ static void netfs_cleanup_dio_write(struct netfs_io_request *wreq)
* Perform an unbuffered write where we may have to do an RMW operation on an * Perform an unbuffered write where we may have to do an RMW operation on an
* encrypted file. This can also be used for direct I/O writes. * encrypted file. This can also be used for direct I/O writes.
*/ */
ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov_iter *iter, static ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov_iter *iter,
struct netfs_group *netfs_group) struct netfs_group *netfs_group)
{ {
struct netfs_io_request *wreq; struct netfs_io_request *wreq;
unsigned long long start = iocb->ki_pos; unsigned long long start = iocb->ki_pos;
...@@ -140,6 +140,7 @@ ssize_t netfs_unbuffered_write_iter(struct kiocb *iocb, struct iov_iter *from) ...@@ -140,6 +140,7 @@ ssize_t netfs_unbuffered_write_iter(struct kiocb *iocb, struct iov_iter *from)
_enter("%llx,%zx,%llx", iocb->ki_pos, iov_iter_count(from), i_size_read(inode)); _enter("%llx,%zx,%llx", iocb->ki_pos, iov_iter_count(from), i_size_read(inode));
trace_netfs_write_iter(iocb, from); trace_netfs_write_iter(iocb, from);
netfs_stat(&netfs_n_rh_dio_write);
ret = netfs_start_io_direct(inode); ret = netfs_start_io_direct(inode);
if (ret < 0) if (ret < 0)
......
...@@ -48,13 +48,15 @@ atomic_t fscache_n_no_create_space; ...@@ -48,13 +48,15 @@ atomic_t fscache_n_no_create_space;
EXPORT_SYMBOL(fscache_n_no_create_space); EXPORT_SYMBOL(fscache_n_no_create_space);
atomic_t fscache_n_culled; atomic_t fscache_n_culled;
EXPORT_SYMBOL(fscache_n_culled); EXPORT_SYMBOL(fscache_n_culled);
atomic_t fscache_n_dio_misfit;
EXPORT_SYMBOL(fscache_n_dio_misfit);
/* /*
* display the general statistics * display the general statistics
*/ */
int fscache_stats_show(struct seq_file *m) int fscache_stats_show(struct seq_file *m)
{ {
seq_puts(m, "FS-Cache statistics\n"); seq_puts(m, "-- FS-Cache statistics --\n");
seq_printf(m, "Cookies: n=%d v=%d vcol=%u voom=%u\n", seq_printf(m, "Cookies: n=%d v=%d vcol=%u voom=%u\n",
atomic_read(&fscache_n_cookies), atomic_read(&fscache_n_cookies),
atomic_read(&fscache_n_volumes), atomic_read(&fscache_n_volumes),
...@@ -93,8 +95,9 @@ int fscache_stats_show(struct seq_file *m) ...@@ -93,8 +95,9 @@ int fscache_stats_show(struct seq_file *m)
atomic_read(&fscache_n_no_create_space), atomic_read(&fscache_n_no_create_space),
atomic_read(&fscache_n_culled)); atomic_read(&fscache_n_culled));
seq_printf(m, "IO : rd=%u wr=%u\n", seq_printf(m, "IO : rd=%u wr=%u mis=%u\n",
atomic_read(&fscache_n_read), atomic_read(&fscache_n_read),
atomic_read(&fscache_n_write)); atomic_read(&fscache_n_write),
atomic_read(&fscache_n_dio_misfit));
return 0; return 0;
} }
...@@ -26,12 +26,6 @@ void netfs_rreq_unlock_folios(struct netfs_io_request *rreq); ...@@ -26,12 +26,6 @@ void netfs_rreq_unlock_folios(struct netfs_io_request *rreq);
int netfs_prefetch_for_write(struct file *file, struct folio *folio, int netfs_prefetch_for_write(struct file *file, struct folio *folio,
size_t offset, size_t len); size_t offset, size_t len);
/*
* direct_write.c
*/
ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov_iter *iter,
struct netfs_group *netfs_group);
/* /*
* io.c * io.c
*/ */
...@@ -110,6 +104,7 @@ int netfs_end_writethrough(struct netfs_io_request *wreq, struct kiocb *iocb); ...@@ -110,6 +104,7 @@ int netfs_end_writethrough(struct netfs_io_request *wreq, struct kiocb *iocb);
*/ */
#ifdef CONFIG_NETFS_STATS #ifdef CONFIG_NETFS_STATS
extern atomic_t netfs_n_rh_dio_read; extern atomic_t netfs_n_rh_dio_read;
extern atomic_t netfs_n_rh_dio_write;
extern atomic_t netfs_n_rh_readahead; extern atomic_t netfs_n_rh_readahead;
extern atomic_t netfs_n_rh_readpage; extern atomic_t netfs_n_rh_readpage;
extern atomic_t netfs_n_rh_rreq; extern atomic_t netfs_n_rh_rreq;
...@@ -128,6 +123,7 @@ extern atomic_t netfs_n_rh_write_begin; ...@@ -128,6 +123,7 @@ extern atomic_t netfs_n_rh_write_begin;
extern atomic_t netfs_n_rh_write_done; extern atomic_t netfs_n_rh_write_done;
extern atomic_t netfs_n_rh_write_failed; extern atomic_t netfs_n_rh_write_failed;
extern atomic_t netfs_n_rh_write_zskip; extern atomic_t netfs_n_rh_write_zskip;
extern atomic_t netfs_n_wh_wstream_conflict;
extern atomic_t netfs_n_wh_upload; extern atomic_t netfs_n_wh_upload;
extern atomic_t netfs_n_wh_upload_done; extern atomic_t netfs_n_wh_upload_done;
extern atomic_t netfs_n_wh_upload_failed; extern atomic_t netfs_n_wh_upload_failed;
......
...@@ -126,7 +126,7 @@ static void netfs_rreq_unmark_after_write(struct netfs_io_request *rreq, ...@@ -126,7 +126,7 @@ static void netfs_rreq_unmark_after_write(struct netfs_io_request *rreq,
*/ */
if (have_unlocked && folio_index(folio) <= unlocked) if (have_unlocked && folio_index(folio) <= unlocked)
continue; continue;
unlocked = folio_index(folio); unlocked = folio_next_index(folio) - 1;
trace_netfs_folio(folio, netfs_folio_trace_end_copy); trace_netfs_folio(folio, netfs_folio_trace_end_copy);
folio_end_fscache(folio); folio_end_fscache(folio);
have_unlocked = true; have_unlocked = true;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "internal.h" #include "internal.h"
atomic_t netfs_n_rh_dio_read; atomic_t netfs_n_rh_dio_read;
atomic_t netfs_n_rh_dio_write;
atomic_t netfs_n_rh_readahead; atomic_t netfs_n_rh_readahead;
atomic_t netfs_n_rh_readpage; atomic_t netfs_n_rh_readpage;
atomic_t netfs_n_rh_rreq; atomic_t netfs_n_rh_rreq;
...@@ -28,6 +29,7 @@ atomic_t netfs_n_rh_write_begin; ...@@ -28,6 +29,7 @@ atomic_t netfs_n_rh_write_begin;
atomic_t netfs_n_rh_write_done; atomic_t netfs_n_rh_write_done;
atomic_t netfs_n_rh_write_failed; atomic_t netfs_n_rh_write_failed;
atomic_t netfs_n_rh_write_zskip; atomic_t netfs_n_rh_write_zskip;
atomic_t netfs_n_wh_wstream_conflict;
atomic_t netfs_n_wh_upload; atomic_t netfs_n_wh_upload;
atomic_t netfs_n_wh_upload_done; atomic_t netfs_n_wh_upload_done;
atomic_t netfs_n_wh_upload_failed; atomic_t netfs_n_wh_upload_failed;
...@@ -37,14 +39,13 @@ atomic_t netfs_n_wh_write_failed; ...@@ -37,14 +39,13 @@ atomic_t netfs_n_wh_write_failed;
int netfs_stats_show(struct seq_file *m, void *v) int netfs_stats_show(struct seq_file *m, void *v)
{ {
seq_printf(m, "Netfs : DR=%u RA=%u RP=%u WB=%u WBZ=%u rr=%u sr=%u\n", seq_printf(m, "Netfs : DR=%u DW=%u RA=%u RP=%u WB=%u WBZ=%u\n",
atomic_read(&netfs_n_rh_dio_read), atomic_read(&netfs_n_rh_dio_read),
atomic_read(&netfs_n_rh_dio_write),
atomic_read(&netfs_n_rh_readahead), atomic_read(&netfs_n_rh_readahead),
atomic_read(&netfs_n_rh_readpage), atomic_read(&netfs_n_rh_readpage),
atomic_read(&netfs_n_rh_write_begin), atomic_read(&netfs_n_rh_write_begin),
atomic_read(&netfs_n_rh_write_zskip), atomic_read(&netfs_n_rh_write_zskip));
atomic_read(&netfs_n_rh_rreq),
atomic_read(&netfs_n_rh_sreq));
seq_printf(m, "Netfs : ZR=%u sh=%u sk=%u\n", seq_printf(m, "Netfs : ZR=%u sh=%u sk=%u\n",
atomic_read(&netfs_n_rh_zero), atomic_read(&netfs_n_rh_zero),
atomic_read(&netfs_n_rh_short_read), atomic_read(&netfs_n_rh_short_read),
...@@ -66,6 +67,10 @@ int netfs_stats_show(struct seq_file *m, void *v) ...@@ -66,6 +67,10 @@ int netfs_stats_show(struct seq_file *m, void *v)
atomic_read(&netfs_n_wh_write), atomic_read(&netfs_n_wh_write),
atomic_read(&netfs_n_wh_write_done), atomic_read(&netfs_n_wh_write_done),
atomic_read(&netfs_n_wh_write_failed)); atomic_read(&netfs_n_wh_write_failed));
seq_printf(m, "Netfs : rr=%u sr=%u wsc=%u\n",
atomic_read(&netfs_n_rh_rreq),
atomic_read(&netfs_n_rh_sreq),
atomic_read(&netfs_n_wh_wstream_conflict));
return fscache_stats_show(m); return fscache_stats_show(m);
} }
EXPORT_SYMBOL(netfs_stats_show); EXPORT_SYMBOL(netfs_stats_show);
...@@ -189,17 +189,20 @@ extern atomic_t fscache_n_write; ...@@ -189,17 +189,20 @@ extern atomic_t fscache_n_write;
extern atomic_t fscache_n_no_write_space; extern atomic_t fscache_n_no_write_space;
extern atomic_t fscache_n_no_create_space; extern atomic_t fscache_n_no_create_space;
extern atomic_t fscache_n_culled; extern atomic_t fscache_n_culled;
extern atomic_t fscache_n_dio_misfit;
#define fscache_count_read() atomic_inc(&fscache_n_read) #define fscache_count_read() atomic_inc(&fscache_n_read)
#define fscache_count_write() atomic_inc(&fscache_n_write) #define fscache_count_write() atomic_inc(&fscache_n_write)
#define fscache_count_no_write_space() atomic_inc(&fscache_n_no_write_space) #define fscache_count_no_write_space() atomic_inc(&fscache_n_no_write_space)
#define fscache_count_no_create_space() atomic_inc(&fscache_n_no_create_space) #define fscache_count_no_create_space() atomic_inc(&fscache_n_no_create_space)
#define fscache_count_culled() atomic_inc(&fscache_n_culled) #define fscache_count_culled() atomic_inc(&fscache_n_culled)
#define fscache_count_dio_misfit() atomic_inc(&fscache_n_dio_misfit)
#else #else
#define fscache_count_read() do {} while(0) #define fscache_count_read() do {} while(0)
#define fscache_count_write() do {} while(0) #define fscache_count_write() do {} while(0)
#define fscache_count_no_write_space() do {} while(0) #define fscache_count_no_write_space() do {} while(0)
#define fscache_count_no_create_space() do {} while(0) #define fscache_count_no_create_space() do {} while(0)
#define fscache_count_culled() do {} while(0) #define fscache_count_culled() do {} while(0)
#define fscache_count_dio_misfit() do {} while(0)
#endif #endif
#endif /* _LINUX_FSCACHE_CACHE_H */ #endif /* _LINUX_FSCACHE_CACHE_H */
...@@ -142,6 +142,7 @@ struct netfs_inode { ...@@ -142,6 +142,7 @@ struct netfs_inode {
#define NETFS_ICTX_ODIRECT 0 /* The file has DIO in progress */ #define NETFS_ICTX_ODIRECT 0 /* The file has DIO in progress */
#define NETFS_ICTX_UNBUFFERED 1 /* I/O should not use the pagecache */ #define NETFS_ICTX_UNBUFFERED 1 /* I/O should not use the pagecache */
#define NETFS_ICTX_WRITETHROUGH 2 /* Write-through caching */ #define NETFS_ICTX_WRITETHROUGH 2 /* Write-through caching */
#define NETFS_ICTX_NO_WRITE_STREAMING 3 /* Don't engage in write-streaming */
}; };
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment