| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/09/09 08:19 | flow | patch-triage |
0mArgs:null Results: {
"EnableConfigs": [
"NETFS_SUPPORT",
"FSCACHE",
"CACHEFILES",
"NETFS_PGPRIV2",
"9P_FS",
"AFS_FS",
"CEPH_FS",
"NFS_FSCACHE"
],
"FocusSymbols": [
"netfs_perform_write",
"netfs_alloc_subrequest",
"netfs_writepages",
"netfs_write_collection",
"netfs_read_collection",
"netfs_folio_written_back",
"cachefiles_begin_operation",
"__cachefiles_prepare_write",
"__cachefiles_write"
],
"KMSANReasoning": "The patch performs internal refactoring within the netfs and fscache subsystems:\n1. Replaces offset and length types (`loff_t` and `unsigned long long`) with `uoff_t`.\n2. Removes the deprecated `NETFS_WRITETHROUGH` path and related writethrough tracking functions.\n3. Modularizes PG_private_2 read support behind `CONFIG_NETFS_PGPRIV2`.\n4. Refactors `netfs_alloc_subrequest` to pass `enum netfs_io_source` on allocation, where memory is explicitly zeroed via `memset`.\n5. Encapsulates `NETFS_RREQ_ALL_QUEUED` flag operations and updates tracepoints.\n\nNo uninitialized variables or memory buffers are introduced, and no data structures copied to user space or used in conditional logic are left uninitialized. Therefore, standard KASAN/lockdep testing is sufficient and a dedicated KMSAN session is not required.",
"NeedsKMSAN": false,
"Reasoning": "The patch series significantly refactors the netfs and fscache subsystems by removing the writethrough write path from netfs_perform_write(), migrating offset/size parameters across netfs and cachefiles to uoff_t, introducing CONFIG_NETFS_PGPRIV2 for modularizing PG_private_2 cache write tracking, refactoring netfs_alloc_subrequest() source initialization, and altering atomic subrequest queue tracking/wake-up logic. These modifications affect core file I/O, buffered write, read collection, and writeback paths in network filesystems (9p, afs, ceph, nfs) and local cachefiles.",
"WorthFuzzing": true
} |
| 1/1 | 2026/09/09 08:19 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit f50aa0a56f8cd08bac1340311f5a577b64be7080\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Wed Sep 9 08:19:43 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c\nindex 1ac0b3dcc0778..2129fcb0f65c1 100644\n--- a/fs/9p/vfs_addr.c\n+++ b/fs/9p/vfs_addr.c\n@@ -124,7 +124,6 @@ static int v9fs_init_request(struct netfs_io_request *rreq, struct file *file)\n \tstruct p9_fid *fid;\n \tstruct dentry *dentry;\n \tbool writing = (rreq-\u003eorigin == NETFS_READ_FOR_WRITE ||\n-\t\t\trreq-\u003eorigin == NETFS_WRITETHROUGH ||\n \t\t\trreq-\u003eorigin == NETFS_UNBUFFERED_WRITE ||\n \t\t\trreq-\u003eorigin == NETFS_DIO_WRITE);\n \ndiff --git a/fs/afs/file.c b/fs/afs/file.c\nindex 0467742bfeee3..99987f6bbc36a 100644\n--- a/fs/afs/file.c\n+++ b/fs/afs/file.c\n@@ -400,7 +400,6 @@ static int afs_init_request(struct netfs_io_request *rreq, struct file *file)\n \t\t}\n \t\tbreak;\n \tcase NETFS_WRITEBACK:\n-\tcase NETFS_WRITETHROUGH:\n \tcase NETFS_UNBUFFERED_WRITE:\n \tcase NETFS_DIO_WRITE:\n \t\tif (S_ISREG(rreq-\u003einode-\u003ei_mode))\n@@ -413,7 +412,7 @@ static int afs_init_request(struct netfs_io_request *rreq, struct file *file)\n \treturn 0;\n }\n \n-static int afs_check_write_begin(struct file *file, loff_t pos, unsigned len,\n+static int afs_check_write_begin(struct file *file, uoff_t pos, unsigned len,\n \t\t\t\t struct folio **foliop, void **_fsdata)\n {\n \tstruct afs_vnode *vnode = AFS_FS_I(file_inode(file));\n@@ -451,7 +450,7 @@ void afs_set_i_size(struct afs_vnode *vnode, loff_t new_i_size)\n \tfscache_update_cookie(afs_vnode_cache(vnode), NULL, \u0026new_i_size);\n }\n \n-static void afs_update_i_size(struct inode *inode, loff_t new_i_size)\n+static void afs_update_i_size(struct inode *inode, uoff_t new_i_size)\n {\n \tafs_set_i_size(AFS_FS_I(inode), new_i_size);\n }\ndiff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c\nindex 50a000310a8c5..a160d5c3e74c0 100644\n--- a/fs/cachefiles/interface.c\n+++ b/fs/cachefiles/interface.c\n@@ -111,7 +111,7 @@ static int cachefiles_adjust_size(struct cachefiles_object *object)\n \tstruct iattr newattrs;\n \tstruct file *file = object-\u003efile;\n \tuint64_t ni_size;\n-\tloff_t oi_size;\n+\tuoff_t oi_size;\n \tint ret;\n \n \tni_size = object-\u003ecookie-\u003eobject_size;\n@@ -225,11 +225,11 @@ static bool cachefiles_lookup_cookie(struct fscache_cookie *cookie)\n * any unused granules.\n */\n static bool cachefiles_shorten_object(struct cachefiles_object *object,\n-\t\t\t\t struct file *file, loff_t new_size)\n+\t\t\t\t struct file *file, uoff_t new_size)\n {\n \tstruct cachefiles_cache *cache = object-\u003evolume-\u003ecache;\n \tstruct inode *inode = file_inode(file);\n-\tloff_t i_size, dio_size;\n+\tuoff_t i_size, dio_size;\n \tint ret;\n \n \tdio_size = round_up(new_size, CACHEFILES_DIO_BLOCK_SIZE);\n@@ -271,14 +271,14 @@ static bool cachefiles_shorten_object(struct cachefiles_object *object,\n * Resize the backing object.\n */\n static void cachefiles_resize_cookie(struct netfs_cache_resources *cres,\n-\t\t\t\t loff_t new_size)\n+\t\t\t\t uoff_t new_size)\n {\n \tstruct cachefiles_object *object = cachefiles_cres_object(cres);\n \tstruct cachefiles_cache *cache = object-\u003evolume-\u003ecache;\n \tstruct fscache_cookie *cookie = object-\u003ecookie;\n \tconst struct cred *saved_cred;\n \tstruct file *file = cachefiles_cres_file(cres);\n-\tloff_t old_size = cookie-\u003eobject_size;\n+\tuoff_t old_size = cookie-\u003eobject_size;\n \n \t_enter(\"%llu-\u003e%llu\", old_size, new_size);\n \ndiff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h\nindex c93324e0f98c7..60bd801ada04f 100644\n--- a/fs/cachefiles/internal.h\n+++ b/fs/cachefiles/internal.h\n@@ -203,11 +203,11 @@ extern bool cachefiles_begin_operation(struct netfs_cache_resources *cres,\n \t\t\t\t enum fscache_want_state want_state);\n extern int __cachefiles_prepare_write(struct cachefiles_object *object,\n \t\t\t\t struct file *file,\n-\t\t\t\t loff_t *_start, size_t *_len, size_t upper_len,\n+\t\t\t\t uoff_t *_start, size_t *_len, size_t upper_len,\n \t\t\t\t bool no_space_allocated_yet);\n extern int __cachefiles_write(struct cachefiles_object *object,\n \t\t\t struct file *file,\n-\t\t\t loff_t start_pos,\n+\t\t\t uoff_t start_pos,\n \t\t\t struct iov_iter *iter,\n \t\t\t netfs_io_terminated_t term_func,\n \t\t\t void *term_func_priv);\ndiff --git a/fs/cachefiles/io.c b/fs/cachefiles/io.c\nindex 9540ec25b3cb6..e61e885784d69 100644\n--- a/fs/cachefiles/io.c\n+++ b/fs/cachefiles/io.c\n@@ -19,7 +19,7 @@\n struct cachefiles_kiocb {\n \tstruct kiocb\t\tiocb;\n \trefcount_t\t\tki_refcnt;\n-\tloff_t\t\t\tstart;\n+\tuoff_t\t\t\tstart;\n \tunion {\n \t\tsize_t\t\tskipped;\n \t\tsize_t\t\tlen;\n@@ -73,7 +73,7 @@ static void cachefiles_read_complete(struct kiocb *iocb, long ret)\n * Initiate a read from the cache.\n */\n static int cachefiles_read(struct netfs_cache_resources *cres,\n-\t\t\t loff_t start_pos,\n+\t\t\t uoff_t start_pos,\n \t\t\t struct iov_iter *iter,\n \t\t\t enum netfs_read_from_hole read_hole,\n \t\t\t netfs_io_terminated_t term_func,\n@@ -197,8 +197,8 @@ static int cachefiles_read(struct netfs_cache_resources *cres,\n * of data starts and how long it is.\n */\n static int cachefiles_query_occupancy(struct netfs_cache_resources *cres,\n-\t\t\t\t loff_t start, size_t len, size_t granularity,\n-\t\t\t\t loff_t *_data_start, size_t *_data_len)\n+\t\t\t\t uoff_t start, size_t len, size_t granularity,\n+\t\t\t\t uoff_t *_data_start, size_t *_data_len)\n {\n \tstruct cachefiles_object *object;\n \tstruct file *file;\n@@ -280,7 +280,7 @@ static void cachefiles_write_complete(struct kiocb *iocb, long ret)\n */\n int __cachefiles_write(struct cachefiles_object *object,\n \t\t struct file *file,\n-\t\t loff_t start_pos,\n+\t\t uoff_t start_pos,\n \t\t struct iov_iter *iter,\n \t\t netfs_io_terminated_t term_func,\n \t\t void *term_func_priv)\n@@ -357,7 +357,7 @@ int __cachefiles_write(struct cachefiles_object *object,\n }\n \n static int cachefiles_write(struct netfs_cache_resources *cres,\n-\t\t\t loff_t start_pos,\n+\t\t\t uoff_t start_pos,\n \t\t\t struct iov_iter *iter,\n \t\t\t netfs_io_terminated_t term_func,\n \t\t\t void *term_func_priv)\n@@ -377,7 +377,7 @@ static int cachefiles_write(struct netfs_cache_resources *cres,\n \n static inline enum netfs_io_source\n cachefiles_do_prepare_read(struct netfs_cache_resources *cres,\n-\t\t\t loff_t start, size_t *_len, loff_t i_size,\n+\t\t\t uoff_t start, size_t *_len, loff_t i_size,\n \t\t\t unsigned long *_flags, ino_t netfs_ino)\n {\n \tenum cachefiles_prepare_read_trace why;\n@@ -483,7 +483,7 @@ cachefiles_do_prepare_read(struct netfs_cache_resources *cres,\n * boundary as appropriate.\n */\n static enum netfs_io_source cachefiles_prepare_read(struct netfs_io_subrequest *subreq,\n-\t\t\t\t\t\t unsigned long long i_size)\n+\t\t\t\t\t\t uoff_t i_size)\n {\n \treturn cachefiles_do_prepare_read(\u0026subreq-\u003erreq-\u003ecache_resources,\n \t\t\t\t\t subreq-\u003estart, \u0026subreq-\u003elen, i_size,\n@@ -495,7 +495,7 @@ static enum netfs_io_source cachefiles_prepare_read(struct netfs_io_subrequest *\n */\n int __cachefiles_prepare_write(struct cachefiles_object *object,\n \t\t\t struct file *file,\n-\t\t\t loff_t *_start, size_t *_len, size_t upper_len,\n+\t\t\t uoff_t *_start, size_t *_len, size_t upper_len,\n \t\t\t bool no_space_allocated_yet)\n {\n \tstruct cachefiles_cache *cache = object-\u003evolume-\u003ecache;\n@@ -577,8 +577,8 @@ int __cachefiles_prepare_write(struct cachefiles_object *object,\n }\n \n static int cachefiles_prepare_write(struct netfs_cache_resources *cres,\n-\t\t\t\t loff_t *_start, size_t *_len, size_t upper_len,\n-\t\t\t\t loff_t i_size, bool no_space_allocated_yet)\n+\t\t\t\t uoff_t *_start, size_t *_len, size_t upper_len,\n+\t\t\t\t uoff_t i_size, bool no_space_allocated_yet)\n {\n \tstruct cachefiles_object *object = cachefiles_cres_object(cres);\n \tstruct cachefiles_cache *cache = object-\u003evolume-\u003ecache;\n@@ -628,7 +628,7 @@ static void cachefiles_issue_write(struct netfs_io_subrequest *subreq)\n \tstruct netfs_io_stream *stream = \u0026wreq-\u003eio_streams[subreq-\u003estream_nr];\n \tconst struct cred *saved_cred;\n \tsize_t off, pre, post, len = subreq-\u003elen;\n-\tloff_t start = subreq-\u003estart;\n+\tuoff_t start = subreq-\u003estart;\n \tint ret;\n \n \t_enter(\"W=%x[%x] %llx-%llx\",\n@@ -721,6 +721,7 @@ bool cachefiles_begin_operation(struct netfs_cache_resources *cres,\n \n \tif (!cachefiles_cres_file(cres)) {\n \t\tcres-\u003eops = \u0026cachefiles_netfs_cache_ops;\n+\t\tcres-\u003eobject_id = object-\u003edebug_id;\n \t\tif (object-\u003efile) {\n \t\t\tspin_lock(\u0026object-\u003elock);\n \t\t\tif (!cres-\u003ecache_priv2 \u0026\u0026 object-\u003efile)\ndiff --git a/fs/ceph/Kconfig b/fs/ceph/Kconfig\nindex 3d64a316ca31d..aa6ccd7794d23 100644\n--- a/fs/ceph/Kconfig\n+++ b/fs/ceph/Kconfig\n@@ -4,6 +4,7 @@ config CEPH_FS\n \tdepends on INET\n \tselect CEPH_LIB\n \tselect NETFS_SUPPORT\n+\tselect NETFS_PGPRIV2\n \tselect FS_ENCRYPTION_ALGS if FS_ENCRYPTION\n \tdefault n\n \thelp\ndiff --git a/fs/ceph/addr.c b/fs/ceph/addr.c\nindex ecf33b66610c8..6586f6c1dc734 100644\n--- a/fs/ceph/addr.c\n+++ b/fs/ceph/addr.c\n@@ -65,7 +65,7 @@\n \t(CONGESTION_ON_THRESH(congestion_kb) -\t\t\t\t\\\n \t (CONGESTION_ON_THRESH(congestion_kb) \u003e\u003e 2))\n \n-static int ceph_netfs_check_write_begin(struct file *file, loff_t pos, unsigned int len,\n+static int ceph_netfs_check_write_begin(struct file *file, uoff_t pos, unsigned int len,\n \t\t\t\t\tstruct folio **foliop, void **_fsdata);\n \n static inline struct ceph_snap_context *page_snap_context(struct page *page)\n@@ -1854,7 +1854,7 @@ ceph_find_incompatible(struct folio *folio)\n \treturn NULL;\n }\n \n-static int ceph_netfs_check_write_begin(struct file *file, loff_t pos, unsigned int len,\n+static int ceph_netfs_check_write_begin(struct file *file, uoff_t pos, unsigned int len,\n \t\t\t\t\tstruct folio **foliop, void **_fsdata)\n {\n \tstruct inode *inode = file_inode(file);\ndiff --git a/fs/netfs/Kconfig b/fs/netfs/Kconfig\nindex 7701c037c3283..d0e7b0971fa3f 100644\n--- a/fs/netfs/Kconfig\n+++ b/fs/netfs/Kconfig\n@@ -22,6 +22,9 @@ config NETFS_STATS\n \t between CPUs. On the other hand, the stats are very useful for\n \t debugging purposes. Saying 'Y' here is recommended.\n \n+config NETFS_PGPRIV2\n+\tbool\n+\n config NETFS_DEBUG\n \tbool \"Enable dynamic debugging netfslib and FS-Cache\"\n \tdepends on NETFS_SUPPORT\ndiff --git a/fs/netfs/Makefile b/fs/netfs/Makefile\nindex b43188d64bd87..54834cde7e568 100644\n--- a/fs/netfs/Makefile\n+++ b/fs/netfs/Makefile\n@@ -11,7 +11,6 @@ netfs-y := \\\n \tmisc.o \\\n \tobjects.o \\\n \tread_collect.o \\\n-\tread_pgpriv2.o \\\n \tread_retry.o \\\n \tread_single.o \\\n \trolling_buffer.o \\\n@@ -19,6 +18,7 @@ netfs-y := \\\n \twrite_issue.o \\\n \twrite_retry.o\n \n+netfs-$(CONFIG_NETFS_PGPRIV2) += read_pgpriv2.o\n netfs-$(CONFIG_NETFS_STATS) += stats.o\n \n netfs-$(CONFIG_FSCACHE) += \\\ndiff --git a/fs/netfs/buffered_read.c b/fs/netfs/buffered_read.c\nindex 424df70a5c30f..68496e1a171f5 100644\n--- a/fs/netfs/buffered_read.c\n+++ b/fs/netfs/buffered_read.c\n@@ -10,9 +10,9 @@\n #include \"internal.h\"\n \n static void netfs_cache_expand_readahead(struct netfs_io_request *rreq,\n-\t\t\t\t\t unsigned long long *_start,\n-\t\t\t\t\t unsigned long long *_len,\n-\t\t\t\t\t unsigned long long i_size)\n+\t\t\t\t\t uoff_t *_start,\n+\t\t\t\t\t uoff_t *_len,\n+\t\t\t\t\t uoff_t i_size)\n {\n \tstruct netfs_cache_resources *cres = \u0026rreq-\u003ecache_resources;\n \n@@ -139,7 +139,7 @@ static ssize_t netfs_prepare_read_iterator(struct netfs_io_subrequest *subreq)\n \n static enum netfs_io_source netfs_cache_prepare_read(struct netfs_io_request *rreq,\n \t\t\t\t\t\t struct netfs_io_subrequest *subreq,\n-\t\t\t\t\t\t loff_t i_size)\n+\t\t\t\t\t\t uoff_t i_size)\n {\n \tstruct netfs_cache_resources *cres = \u0026rreq-\u003ecache_resources;\n \tenum netfs_io_source source;\n@@ -242,7 +242,7 @@ static void netfs_mark_copy_to_cache(struct netfs_io_request *rreq,\n \n \t\tif (overlap \u003e 0 \u0026\u0026 copy) {\n \t\t\tfolio = folioq_folio(*fq, *slot);\n-\t\t\tif (unlikely(test_bit(NETFS_RREQ_USE_PGPRIV2, \u0026rreq-\u003eflags))) {\n+\t\t\tif (netfs_using_pgpriv2(rreq)) {\n \t\t\t\tif (!folio_test_private_2(folio))\n \t\t\t\t\tfolio_start_private_2(folio);\n \t\t\t} else {\n@@ -269,17 +269,17 @@ static void netfs_mark_copy_to_cache(struct netfs_io_request *rreq,\n static void netfs_read_to_pagecache(struct netfs_io_request *rreq)\n {\n \tstruct folio_queue *fq = rreq-\u003ebuffer.tail;\n-\tunsigned long long start = rreq-\u003estart;\n \tunsigned int offset = 0;\n \tssize_t size = rreq-\u003elen;\n+\tuoff_t start = rreq-\u003estart;\n \tint ret = 0, slot = 0;\n \n \tdo {\n \t\tstruct netfs_io_subrequest *subreq;\n-\t\tenum netfs_io_source source = NETFS_SOURCE_UNKNOWN;\n+\t\tenum netfs_io_source source;\n \t\tssize_t slice;\n \n-\t\tsubreq = netfs_alloc_subrequest(rreq);\n+\t\tsubreq = netfs_alloc_subrequest(rreq, NETFS_SOURCE_UNKNOWN);\n \t\tif (!subreq) {\n \t\t\tret = -ENOMEM;\n \t\t\tbreak;\n@@ -293,8 +293,8 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)\n \t\tsource = netfs_cache_prepare_read(rreq, subreq, rreq-\u003ei_size);\n \t\tsubreq-\u003esource = source;\n \t\tif (source == NETFS_DOWNLOAD_FROM_SERVER) {\n-\t\t\tunsigned long long zero_point = netfs_read_zero_point(rreq-\u003einode);\n-\t\t\tunsigned long long zp = umin(zero_point, rreq-\u003ei_size);\n+\t\t\tuoff_t zero_point = netfs_read_zero_point(rreq-\u003einode);\n+\t\t\tuoff_t zp = umin(zero_point, rreq-\u003ei_size);\n \t\t\tsize_t len = subreq-\u003elen;\n \n \t\t\tif (unlikely(rreq-\u003eorigin == NETFS_READ_SINGLE))\n@@ -355,10 +355,8 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)\n \t\t}\n \t\tstart += slice;\n \t\tsize -= slice;\n-\t\tif (size \u003c= 0) {\n-\t\t\tsmp_wmb(); /* Write lists before ALL_QUEUED. */\n-\t\t\tset_bit(NETFS_RREQ_ALL_QUEUED, \u0026rreq-\u003eflags);\n-\t\t}\n+\t\tif (size \u003c= 0)\n+\t\t\tnetfs_all_subreqs_queued(rreq);\n \n \t\tif (fq) {\n \t\t\t/* See if the cache indicated this should be cached. */\n@@ -378,8 +376,7 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)\n \t} while (size \u003e 0);\n \n \tif (unlikely(size \u003e 0)) {\n-\t\tsmp_wmb(); /* Write lists before ALL_QUEUED. */\n-\t\tset_bit(NETFS_RREQ_ALL_QUEUED, \u0026rreq-\u003eflags);\n+\t\tnetfs_all_subreqs_queued(rreq);\n \t\tnetfs_wake_collector(rreq);\n \t}\n \n@@ -642,11 +639,11 @@ EXPORT_SYMBOL(netfs_read_folio);\n * If any of these criteria are met, then zero out the unwritten parts\n * of the folio and return true. Otherwise, return false.\n */\n-static bool netfs_skip_folio_read(struct folio *folio, loff_t pos, size_t len,\n+static bool netfs_skip_folio_read(struct folio *folio, uoff_t pos, size_t len,\n \t\t\t\t bool always_fill)\n {\n \tstruct inode *inode = folio_inode(folio);\n-\tloff_t i_size = i_size_read(inode);\n+\tuoff_t i_size = i_size_read(inode);\n \tsize_t offset = offset_in_folio(folio, pos);\n \tsize_t plen = folio_size(folio);\n \n@@ -711,7 +708,7 @@ static bool netfs_skip_folio_read(struct folio *folio, loff_t pos, size_t len,\n */\n int netfs_write_begin(struct netfs_inode *ctx,\n \t\t struct file *file, struct address_space *mapping,\n-\t\t loff_t pos, unsigned int len, struct folio **_folio,\n+\t\t uoff_t pos, unsigned int len, struct folio **_folio,\n \t\t void **_fsdata)\n {\n \tstruct netfs_io_request *rreq;\n@@ -807,7 +804,7 @@ int netfs_prefetch_for_write(struct file *file, struct folio *folio,\n \tstruct netfs_io_request *rreq;\n \tstruct address_space *mapping = folio-\u003emapping;\n \tstruct netfs_inode *ctx = netfs_inode(mapping-\u003ehost);\n-\tunsigned long long start = folio_pos(folio);\n+\tuoff_t start = folio_pos(folio);\n \tsize_t flen = folio_size(folio);\n \tint ret;\n \ndiff --git a/fs/netfs/buffered_write.c b/fs/netfs/buffered_write.c\nindex 2cdb68e6b16ff..ead22980075fe 100644\n--- a/fs/netfs/buffered_write.c\n+++ b/fs/netfs/buffered_write.c\n@@ -17,7 +17,7 @@\n * as possible to hold as much of the remaining length as possible in one go.\n */\n static struct folio *netfs_grab_folio_for_write(struct address_space *mapping,\n-\t\t\t\t\t\tloff_t pos, size_t part)\n+\t\t\t\t\t\tuoff_t pos, size_t part)\n {\n \tpgoff_t index = pos / PAGE_SIZE;\n \tfgf_t fgp_flags = FGP_WRITEBEGIN;\n@@ -35,9 +35,9 @@ static struct folio *netfs_grab_folio_for_write(struct address_space *mapping,\n * the values actually are.\n */\n void netfs_update_i_size(struct netfs_inode *ctx, struct inode *inode,\n-\t\t\t loff_t pos, size_t copied)\n+\t\t\t uoff_t pos, size_t copied)\n {\n-\tloff_t i_size, end = pos + copied;\n+\tuoff_t i_size, end = pos + copied;\n \tblkcnt_t add;\n \tsize_t gap;\n \n@@ -91,50 +91,20 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter,\n \tstruct inode *inode = file_inode(file);\n \tstruct address_space *mapping = inode-\u003ei_mapping;\n \tstruct netfs_inode *ctx = netfs_inode(inode);\n-\tstruct writeback_control wbc = {\n-\t\t.sync_mode\t= WB_SYNC_NONE,\n-\t\t.for_sync\t= true,\n-\t\t.nr_to_write\t= LONG_MAX,\n-\t\t.range_start\t= iocb-\u003eki_pos,\n-\t\t.range_end\t= iocb-\u003eki_pos + iter-\u003ecount,\n-\t};\n-\tstruct netfs_io_request *wreq = NULL;\n-\tstruct folio *folio = NULL, *writethrough = NULL;\n+\tstruct folio *folio = NULL;\n \tunsigned int bdp_flags = (iocb-\u003eki_flags \u0026 IOCB_NOWAIT) ? BDP_ASYNC : 0;\n-\tssize_t written = 0, ret, ret2;\n-\tloff_t pos = iocb-\u003eki_pos;\n+\tssize_t written = 0, ret;\n+\tuoff_t pos = iocb-\u003eki_pos;\n \tsize_t max_chunk = mapping_max_folio_size(mapping);\n \tbool maybe_trouble = false;\n \n-\tif (unlikely(iocb-\u003eki_flags \u0026 (IOCB_DSYNC | IOCB_SYNC))\n-\t ) {\n-\t\twbc_attach_fdatawrite_inode(\u0026wbc, mapping-\u003ehost);\n-\n-\t\tret = filemap_write_and_wait_range(mapping, pos, pos + iter-\u003ecount);\n-\t\tif (ret \u003c 0) {\n-\t\t\twbc_detach_inode(\u0026wbc);\n-\t\t\tgoto out;\n-\t\t}\n-\n-\t\twreq = netfs_begin_writethrough(iocb, iter-\u003ecount);\n-\t\tif (IS_ERR(wreq)) {\n-\t\t\twbc_detach_inode(\u0026wbc);\n-\t\t\tret = PTR_ERR(wreq);\n-\t\t\twreq = NULL;\n-\t\t\tgoto out;\n-\t\t}\n-\t\tif (!is_sync_kiocb(iocb))\n-\t\t\twreq-\u003eiocb = iocb;\n-\t\tnetfs_stat(\u0026netfs_n_wh_writethrough);\n-\t} else {\n-\t\tnetfs_stat(\u0026netfs_n_wh_buffered_write);\n-\t}\n+\tnetfs_stat(\u0026netfs_n_wh_buffered_write);\n \n \tdo {\n \t\tenum netfs_folio_trace trace;\n \t\tstruct netfs_folio *finfo;\n \t\tstruct netfs_group *group;\n-\t\tunsigned long long fpos;\n+\t\tuoff_t fpos;\n \t\tsize_t flen;\n \t\tsize_t offset;\t/* Offset into pagecache folio */\n \t\tsize_t part;\t/* Bytes to write to folio */\n@@ -390,15 +360,8 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter,\n \t\tpos += copied;\n \t\twritten += copied;\n \n-\t\tif (likely(!wreq)) {\n-\t\t\tfolio_mark_dirty(folio);\n-\t\t\tfolio_unlock(folio);\n-\t\t} else {\n-\t\t\tnetfs_advance_writethrough(wreq, \u0026wbc, folio, copied,\n-\t\t\t\t\t\t offset + copied == flen,\n-\t\t\t\t\t\t \u0026writethrough);\n-\t\t\t/* Folio unlocked */\n-\t\t}\n+\t\tfolio_mark_dirty(folio);\n+\t\tfolio_unlock(folio);\n \tretry:\n \t\tfolio_put(folio);\n \t\tfolio = NULL;\n@@ -420,15 +383,6 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter,\n \t\t\tctx-\u003eops-\u003epost_modify(inode);\n \t}\n \n-\tif (unlikely(wreq)) {\n-\t\tret2 = netfs_end_writethrough(wreq, \u0026wbc, writethrough);\n-\t\twbc_detach_inode(\u0026wbc);\n-\t\tif (ret2 == -EIOCBQUEUED)\n-\t\t\treturn ret2;\n-\t\tif (ret == 0 \u0026\u0026 ret2 \u003c 0)\n-\t\t\tret = ret2;\n-\t}\n-\n \tiocb-\u003eki_pos += written;\n \t_leave(\" = %zd [%zd]\", written, ret);\n \treturn written ? written : ret;\ndiff --git a/fs/netfs/direct_read.c b/fs/netfs/direct_read.c\nindex 6a8fb0d55e040..8c15f30797238 100644\n--- a/fs/netfs/direct_read.c\n+++ b/fs/netfs/direct_read.c\n@@ -47,15 +47,15 @@ static void netfs_prepare_dio_read_iterator(struct netfs_io_subrequest *subreq)\n */\n static void netfs_dispatch_unbuffered_reads(struct netfs_io_request *rreq)\n {\n-\tunsigned long long start = rreq-\u003estart;\n \tssize_t size = rreq-\u003elen;\n+\tuoff_t start = rreq-\u003estart;\n \tint ret;\n \n \tdo {\n \t\tstruct netfs_io_subrequest *subreq;\n \t\tssize_t slice;\n \n-\t\tsubreq = netfs_alloc_subrequest(rreq);\n+\t\tsubreq = netfs_alloc_subrequest(rreq, NETFS_DOWNLOAD_FROM_SERVER);\n \t\tif (!subreq) {\n \t\t\t/* Stash the error in the request if there's not\n \t\t\t * already an error set.\n@@ -64,7 +64,6 @@ static void netfs_dispatch_unbuffered_reads(struct netfs_io_request *rreq)\n \t\t\tbreak;\n \t\t}\n \n-\t\tsubreq-\u003esource\t= NETFS_DOWNLOAD_FROM_SERVER;\n \t\tsubreq-\u003estart\t= start;\n \t\tsubreq-\u003elen\t= size;\n \n@@ -84,10 +83,8 @@ static void netfs_dispatch_unbuffered_reads(struct netfs_io_request *rreq)\n \t\tsize -= slice;\n \t\tstart += slice;\n \t\trreq-\u003esubmitted += slice;\n-\t\tif (size \u003c= 0) {\n-\t\t\tsmp_wmb(); /* Write lists before ALL_QUEUED. */\n-\t\t\tset_bit(NETFS_RREQ_ALL_QUEUED, \u0026rreq-\u003eflags);\n-\t\t}\n+\t\tif (size \u003c= 0)\n+\t\t\tnetfs_all_subreqs_queued(rreq);\n \n \t\trreq-\u003enetfs_ops-\u003eissue_read(subreq);\n \n@@ -99,8 +96,7 @@ static void netfs_dispatch_unbuffered_reads(struct netfs_io_request *rreq)\n \t} while (size \u003e 0);\n \n \tif (unlikely(size \u003e 0)) {\n-\t\tsmp_wmb(); /* Write lists before ALL_QUEUED. */\n-\t\tset_bit(NETFS_RREQ_ALL_QUEUED, \u0026rreq-\u003eflags);\n+\t\tnetfs_all_subreqs_queued(rreq);\n \t\tnetfs_wake_collector(rreq);\n \t}\n }\ndiff --git a/fs/netfs/direct_write.c b/fs/netfs/direct_write.c\nindex 2361277416c73..32200c10d2a45 100644\n--- a/fs/netfs/direct_write.c\n+++ b/fs/netfs/direct_write.c\n@@ -225,9 +225,9 @@ ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov_iter *\n \t\t\t\t\t\t struct netfs_group *netfs_group)\n {\n \tstruct netfs_io_request *wreq;\n-\tunsigned long long start = iocb-\u003eki_pos;\n-\tunsigned long long end = start + iov_iter_count(iter);\n \tssize_t ret, n;\n+\tuoff_t start = iocb-\u003eki_pos;\n+\tuoff_t end = start + iov_iter_count(iter);\n \tsize_t len = iov_iter_count(iter);\n \tbool async = !is_sync_kiocb(iocb);\n \n@@ -336,8 +336,8 @@ ssize_t netfs_unbuffered_write_iter(struct kiocb *iocb, struct iov_iter *from)\n \tstruct inode *inode = mapping-\u003ehost;\n \tstruct netfs_inode *ictx = netfs_inode(inode);\n \tssize_t ret;\n-\tloff_t pos = iocb-\u003eki_pos;\n-\tunsigned long long end = pos + iov_iter_count(from) - 1;\n+\tuoff_t pos = iocb-\u003eki_pos;\n+\tuoff_t end = pos + iov_iter_count(from) - 1;\n \n \t_enter(\"%llx,%zx,%llx\", pos, iov_iter_count(from), i_size_read(inode));\n \ndiff --git a/fs/netfs/fscache_cookie.c b/fs/netfs/fscache_cookie.c\nindex 3d56fc73435ff..5a226f9cbdeaa 100644\n--- a/fs/netfs/fscache_cookie.c\n+++ b/fs/netfs/fscache_cookie.c\n@@ -327,7 +327,7 @@ static struct fscache_cookie *fscache_alloc_cookie(\n \tu8 advice,\n \tconst void *index_key, size_t index_key_len,\n \tconst void *aux_data, size_t aux_data_len,\n-\tloff_t object_size)\n+\tuoff_t object_size)\n {\n \tstruct fscache_cookie *cookie;\n \n@@ -452,7 +452,7 @@ struct fscache_cookie *__fscache_acquire_cookie(\n \tu8 advice,\n \tconst void *index_key, size_t index_key_len,\n \tconst void *aux_data, size_t aux_data_len,\n-\tloff_t object_size)\n+\tuoff_t object_size)\n {\n \tstruct fscache_cookie *cookie;\n \n@@ -663,7 +663,7 @@ static void fscache_unuse_cookie_locked(struct fscache_cookie *cookie)\n * Stop using the cookie for I/O.\n */\n void __fscache_unuse_cookie(struct fscache_cookie *cookie,\n-\t\t\t const void *aux_data, const loff_t *object_size)\n+\t\t\t const void *aux_data, const uoff_t *object_size)\n {\n \tunsigned int debug_id = cookie-\u003edebug_id;\n \tunsigned int r = refcount_read(\u0026cookie-\u003eref);\n@@ -1049,7 +1049,7 @@ static void fscache_perform_invalidation(struct fscache_cookie *cookie)\n * Invalidate an object.\n */\n void __fscache_invalidate(struct fscache_cookie *cookie,\n-\t\t\t const void *aux_data, loff_t new_size,\n+\t\t\t const void *aux_data, uoff_t new_size,\n \t\t\t unsigned int flags)\n {\n \tbool is_caching;\ndiff --git a/fs/netfs/fscache_io.c b/fs/netfs/fscache_io.c\nindex 37f05b4d34699..056a2bae5d99a 100644\n--- a/fs/netfs/fscache_io.c\n+++ b/fs/netfs/fscache_io.c\n@@ -79,7 +79,7 @@ static int fscache_begin_operation(struct netfs_cache_resources *cres,\n \tcres-\u003eops\t\t= NULL;\n \tcres-\u003ecache_priv\t= cookie;\n \tcres-\u003ecache_priv2\t= NULL;\n-\tcres-\u003edebug_id\t\t= cookie-\u003edebug_id;\n+\tcres-\u003ecookie_id\t\t= cookie-\u003edebug_id;\n \tcres-\u003einval_counter\t= cookie-\u003einval_counter;\n \n \tif (!fscache_begin_cookie_access(cookie, why)) {\n@@ -162,7 +162,7 @@ EXPORT_SYMBOL(__fscache_begin_write_operation);\n struct fscache_write_request {\n \tstruct netfs_cache_resources cache_resources;\n \tstruct address_space\t*mapping;\n-\tloff_t\t\t\tstart;\n+\tuoff_t\t\t\tstart;\n \tsize_t\t\t\tlen;\n \tbool\t\t\tset_bits;\n \tbool\t\t\tusing_pgpriv2;\n@@ -171,7 +171,7 @@ struct fscache_write_request {\n };\n \n void __fscache_clear_page_bits(struct address_space *mapping,\n-\t\t\t loff_t start, size_t len)\n+\t\t\t uoff_t start, size_t len)\n {\n \tpgoff_t first = start / PAGE_SIZE;\n \tpgoff_t last = (start + len - 1) / PAGE_SIZE;\n@@ -208,7 +208,7 @@ static void fscache_wreq_done(void *priv, ssize_t transferred_or_error)\n \n void __fscache_write_to_cache(struct fscache_cookie *cookie,\n \t\t\t struct address_space *mapping,\n-\t\t\t loff_t start, size_t len, loff_t i_size,\n+\t\t\t uoff_t start, size_t len, uoff_t i_size,\n \t\t\t netfs_io_terminated_t term_func,\n \t\t\t void *term_func_priv,\n \t\t\t bool using_pgpriv2, bool cond)\n@@ -267,7 +267,7 @@ EXPORT_SYMBOL(__fscache_write_to_cache);\n /*\n * Change the size of a backing object.\n */\n-void __fscache_resize_cookie(struct fscache_cookie *cookie, loff_t new_size)\n+void __fscache_resize_cookie(struct fscache_cookie *cookie, uoff_t new_size)\n {\n \tstruct netfs_cache_resources cres;\n \ndiff --git a/fs/netfs/internal.h b/fs/netfs/internal.h\nindex c79c8e69d60ca..4891e6e3c5db6 100644\n--- a/fs/netfs/internal.h\n+++ b/fs/netfs/internal.h\n@@ -33,7 +33,7 @@ int netfs_prefetch_for_write(struct file *file, struct folio *folio,\n * buffered_write.c\n */\n void netfs_update_i_size(struct netfs_inode *ctx, struct inode *inode,\n-\t\t\t loff_t pos, size_t copied);\n+\t\t\t uoff_t pos, size_t copied);\n \n /*\n * main.c\n@@ -86,13 +86,14 @@ void netfs_wait_for_put_ra_refs(struct netfs_io_request *rreq);\n */\n struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,\n \t\t\t\t\t struct file *file,\n-\t\t\t\t\t loff_t start, size_t len,\n+\t\t\t\t\t uoff_t start, size_t len,\n \t\t\t\t\t enum netfs_io_origin origin);\n void netfs_get_request(struct netfs_io_request *rreq, enum netfs_rreq_ref_trace what);\n void netfs_clear_subrequests(struct netfs_io_request *rreq);\n void netfs_put_request(struct netfs_io_request *rreq, enum netfs_rreq_ref_trace what);\n void netfs_put_failed_request(struct netfs_io_request *rreq);\n-struct netfs_io_subrequest *netfs_alloc_subrequest(struct netfs_io_request *rreq);\n+struct netfs_io_subrequest *netfs_alloc_subrequest(struct netfs_io_request *rreq,\n+\t\t\t\t\t\t enum netfs_io_source source);\n \n static inline void netfs_see_request(struct netfs_io_request *rreq,\n \t\t\t\t enum netfs_rreq_ref_trace what)\n@@ -120,9 +121,37 @@ void netfs_cache_read_terminated(void *priv, ssize_t transferred_or_error);\n /*\n * read_pgpriv2.c\n */\n+#ifdef CONFIG_NETFS_PGPRIV2\n+int netfs_prepare_pgpriv2_write_buffer(struct netfs_io_subrequest *subreq,\n+\t\t\t\t unsigned int max_segs);\n void netfs_pgpriv2_copy_to_cache(struct netfs_io_request *rreq, struct folio *folio);\n void netfs_pgpriv2_end_copy_to_cache(struct netfs_io_request *rreq);\n bool netfs_pgpriv2_unlock_copied_folios(struct netfs_io_request *wreq);\n+static inline bool netfs_using_pgpriv2(const struct netfs_io_request *rreq)\n+{\n+\treturn unlikely(test_bit(NETFS_RREQ_USE_PGPRIV2, \u0026rreq-\u003eflags));\n+}\n+#else\n+static inline int netfs_prepare_pgpriv2_write_buffer(struct netfs_io_subrequest *subreq,\n+\t\t\t\t\t\t unsigned int max_segs)\n+{\n+\treturn -EIO;\n+}\n+static inline void netfs_pgpriv2_copy_to_cache(struct netfs_io_request *rreq, struct folio *folio)\n+{\n+}\n+static inline void netfs_pgpriv2_end_copy_to_cache(struct netfs_io_request *rreq)\n+{\n+}\n+static inline bool netfs_pgpriv2_unlock_copied_folios(struct netfs_io_request *wreq)\n+{\n+\treturn true;\n+}\n+static inline bool netfs_using_pgpriv2(const struct netfs_io_request *rreq)\n+{\n+\treturn false;\n+}\n+#endif\n \n /*\n * read_retry.c\n@@ -157,7 +186,6 @@ extern atomic_t netfs_n_rh_write_zskip;\n extern atomic_t netfs_n_rh_retry_read_req;\n extern atomic_t netfs_n_rh_retry_read_subreq;\n extern atomic_t netfs_n_wh_buffered_write;\n-extern atomic_t netfs_n_wh_writethrough;\n extern atomic_t netfs_n_wh_dio_write;\n extern atomic_t netfs_n_wh_writepages;\n extern atomic_t netfs_n_wh_copy_to_cache;\n@@ -203,11 +231,11 @@ void netfs_write_collection_worker(struct work_struct *work);\n */\n struct netfs_io_request *netfs_create_write_req(struct address_space *mapping,\n \t\t\t\t\t\tstruct file *file,\n-\t\t\t\t\t\tloff_t start,\n+\t\t\t\t\t\tuoff_t start,\n \t\t\t\t\t\tenum netfs_io_origin origin);\n void netfs_prepare_write(struct netfs_io_request *wreq,\n \t\t\t struct netfs_io_stream *stream,\n-\t\t\t loff_t start);\n+\t\t\t uoff_t start);\n void netfs_reissue_write(struct netfs_io_stream *stream,\n \t\t\t struct netfs_io_subrequest *subreq,\n \t\t\t struct iov_iter *source);\n@@ -215,13 +243,7 @@ void netfs_issue_write(struct netfs_io_request *wreq,\n \t\t struct netfs_io_stream *stream);\n size_t netfs_advance_write(struct netfs_io_request *wreq,\n \t\t\t struct netfs_io_stream *stream,\n-\t\t\t loff_t start, size_t len, bool to_eof);\n-struct netfs_io_request *netfs_begin_writethrough(struct kiocb *iocb, size_t len);\n-int netfs_advance_writethrough(struct netfs_io_request *wreq, struct writeback_control *wbc,\n-\t\t\t struct folio *folio, size_t copied, bool to_page_end,\n-\t\t\t struct folio **writethrough_cache);\n-ssize_t netfs_end_writethrough(struct netfs_io_request *wreq, struct writeback_control *wbc,\n-\t\t\t struct folio *writethrough_cache);\n+\t\t\t uoff_t start, size_t len, bool to_eof);\n \n /*\n * write_retry.c\n@@ -320,6 +342,26 @@ static inline bool netfs_check_subreq_in_progress(const struct netfs_io_subreque\n \treturn test_bit_acquire(NETFS_SREQ_IN_PROGRESS, \u0026subreq-\u003eflags);\n }\n \n+/*\n+ * Indicate that we've generated and queued all the subrequests we're going to.\n+ */\n+static inline void netfs_all_subreqs_queued(struct netfs_io_request *rreq)\n+{\n+\tsmp_wmb(); /* Write lists before ALL_QUEUED. */\n+\tset_bit(NETFS_RREQ_ALL_QUEUED, \u0026rreq-\u003eflags);\n+\tsmp_mb__after_atomic();\n+\ttrace_netfs_rreq(rreq, netfs_rreq_trace_all_queued);\n+}\n+\n+/*\n+ * Query if all subrequests are queued.\n+ */\n+static inline bool netfs_are_all_subreqs_queued(const struct netfs_io_request *rreq)\n+{\n+\t/* Read lists after ALL_QUEUED. */\n+\treturn test_bit_acquire(NETFS_RREQ_ALL_QUEUED, \u0026rreq-\u003eflags);\n+}\n+\n /*\n * fscache-cache.c\n */\ndiff --git a/fs/netfs/iterator.c b/fs/netfs/iterator.c\nindex b375567e0520e..eb1efb17f53aa 100644\n--- a/fs/netfs/iterator.c\n+++ b/fs/netfs/iterator.c\n@@ -209,7 +209,7 @@ static size_t netfs_limit_xarray(const struct iov_iter *iter, size_t start_offse\n {\n \tstruct folio *folio;\n \tunsigned int nsegs = 0;\n-\tloff_t pos = iter-\u003exarray_start + iter-\u003eiov_offset;\n+\tuoff_t pos = iter-\u003exarray_start + iter-\u003eiov_offset;\n \tpgoff_t index = pos / PAGE_SIZE;\n \tsize_t span = 0, n = iter-\u003ecount;\n \ndiff --git a/fs/netfs/main.c b/fs/netfs/main.c\nindex 927badf3989db..609e22e8f76a0 100644\n--- a/fs/netfs/main.c\n+++ b/fs/netfs/main.c\n@@ -44,7 +44,6 @@ static const char *netfs_origins[nr__netfs_io_origin] = {\n \t[NETFS_DIO_READ]\t\t= \"DR\",\n \t[NETFS_WRITEBACK]\t\t= \"WB\",\n \t[NETFS_WRITEBACK_SINGLE]\t= \"W1\",\n-\t[NETFS_WRITETHROUGH]\t\t= \"WT\",\n \t[NETFS_UNBUFFERED_WRITE]\t= \"UW\",\n \t[NETFS_DIO_WRITE]\t\t= \"DW\",\n \t[NETFS_PGPRIV2_COPY_TO_CACHE]\t= \"2C\",\ndiff --git a/fs/netfs/misc.c b/fs/netfs/misc.c\nindex f5c1c463f4ff7..a3cd76d584b8b 100644\n--- a/fs/netfs/misc.c\n+++ b/fs/netfs/misc.c\n@@ -193,7 +193,7 @@ void netfs_clear_inode_writeback(struct inode *inode, const void *aux)\n \tstruct fscache_cookie *cookie = netfs_i_cookie(netfs_inode(inode));\n \n \tif (inode_state_read_once(inode) \u0026 I_PINNING_NETFS_WB) {\n-\t\tloff_t i_size = i_size_read(inode);\n+\t\tuoff_t i_size = i_size_read(inode);\n \t\tfscache_unuse_cookie(cookie, aux, \u0026i_size);\n \t}\n }\n@@ -218,8 +218,8 @@ void netfs_invalidate_folio(struct folio *folio, size_t offset, size_t length)\n \t_enter(\"{%lx},%zx,%zx\", folio-\u003eindex, offset, length);\n \n \tif (offset == 0 \u0026\u0026 length == flen) {\n-\t\tunsigned long long i_size, remote_i_size, zero_point;\n-\t\tunsigned long long fpos = folio_pos(folio), end;\n+\t\tuoff_t i_size, remote_i_size, zero_point;\n+\t\tuoff_t fpos = folio_pos(folio), end;\n \n \t\tnetfs_read_sizes(inode, \u0026i_size, \u0026remote_i_size, \u0026zero_point);\n \t\tend = umin(fpos + flen, i_size);\n@@ -305,7 +305,7 @@ bool netfs_release_folio(struct folio *folio, gfp_t gfp)\n {\n \tstruct inode *inode = folio_inode(folio);\n \tstruct netfs_inode *ctx = netfs_inode(inode);\n-\tunsigned long long i_size, remote_i_size, zero_point, end;\n+\tuoff_t i_size, remote_i_size, zero_point, end;\n \n \tif (folio_test_dirty(folio))\n \t\treturn false;\n@@ -424,7 +424,7 @@ static int netfs_collect_in_app(struct netfs_io_request *rreq,\n \t\t\tneed_collect = true;\n \t\t\tbreak;\n \t\t}\n-\t\tif (subreq || !test_bit(NETFS_RREQ_ALL_QUEUED, \u0026rreq-\u003eflags))\n+\t\tif (subreq || !netfs_are_all_subreqs_queued(rreq))\n \t\t\tdone = false;\n \t}\n \ndiff --git a/fs/netfs/objects.c b/fs/netfs/objects.c\nindex 7f6a3e912602e..9c6ea718692a7 100644\n--- a/fs/netfs/objects.c\n+++ b/fs/netfs/objects.c\n@@ -16,7 +16,7 @@ static void netfs_free_request(struct work_struct *work);\n */\n struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,\n \t\t\t\t\t struct file *file,\n-\t\t\t\t\t loff_t start, size_t len,\n+\t\t\t\t\t uoff_t start, size_t len,\n \t\t\t\t\t enum netfs_io_origin origin)\n {\n \tstatic atomic_t debug_ids;\n@@ -207,7 +207,8 @@ void netfs_put_failed_request(struct netfs_io_request *rreq)\n /*\n * Allocate and partially initialise an I/O request structure.\n */\n-struct netfs_io_subrequest *netfs_alloc_subrequest(struct netfs_io_request *rreq)\n+struct netfs_io_subrequest *netfs_alloc_subrequest(struct netfs_io_request *rreq,\n+\t\t\t\t\t\t enum netfs_io_source source)\n {\n \tstruct netfs_io_subrequest *subreq;\n \tmempool_t *mempool = rreq-\u003enetfs_ops-\u003esubrequest_pool ?: \u0026netfs_subrequest_pool;\n@@ -224,6 +225,7 @@ struct netfs_io_subrequest *netfs_alloc_subrequest(struct netfs_io_request *rreq\n \tINIT_WORK(\u0026subreq-\u003ework, NULL);\n \tINIT_LIST_HEAD(\u0026subreq-\u003erreq_link);\n \trefcount_set(\u0026subreq-\u003eref, 2);\n+\tsubreq-\u003esource = source;\n \tsubreq-\u003erreq = rreq;\n \tsubreq-\u003edebug_index = atomic_inc_return(\u0026rreq-\u003esubreq_counter);\n \tnetfs_get_request(rreq, netfs_rreq_trace_get_subreq);\ndiff --git a/fs/netfs/read_collect.c b/fs/netfs/read_collect.c\nindex 5cf22087d2439..cb97dedad170f 100644\n--- a/fs/netfs/read_collect.c\n+++ b/fs/netfs/read_collect.c\n@@ -38,7 +38,7 @@ static void netfs_clear_unread(struct netfs_io_subrequest *subreq)\n */\n void netfs_cancel_copy_to_cache(struct netfs_io_request *rreq, struct folio *folio)\n {\n-\tif (!test_bit(NETFS_RREQ_USE_PGPRIV2, \u0026rreq-\u003eflags)) {\n+\tif (!netfs_using_pgpriv2(rreq)) {\n \t\tif (folio_get_private(folio) == NETFS_FOLIO_COPY_TO_CACHE) {\n \t\t\tfolio_detach_private(folio);\n \t\t\ttrace_netfs_folio(folio, netfs_folio_trace_cancel_copy);\n@@ -81,7 +81,7 @@ static void netfs_unlock_read_folio(struct netfs_io_request *rreq,\n \tif (unlikely(test_bit(NETFS_RREQ_CANCEL_CACHING, \u0026rreq-\u003eflags)))\n \t\tnetfs_cancel_copy_to_cache(rreq, folio);\n \n-\tif (!test_bit(NETFS_RREQ_USE_PGPRIV2, \u0026rreq-\u003eflags)) {\n+\tif (!netfs_using_pgpriv2(rreq)) {\n \t\tif (netfs_folio_group(folio) == NETFS_FOLIO_COPY_TO_CACHE) {\n \t\t\ttrace_netfs_folio(folio, netfs_folio_trace_sched_copy);\n \t\t\tfolio_mark_dirty(folio);\n@@ -153,8 +153,8 @@ static void netfs_read_unlock_folios(struct netfs_io_request *rreq,\n \t\t\t\t unsigned int *notes)\n {\n \tstruct folio_queue *folioq = rreq-\u003ebuffer.tail;\n-\tunsigned long long collected_to = rreq-\u003ecollected_to;\n \tunsigned int slot = rreq-\u003ebuffer.first_tail_slot;\n+\tuoff_t collected_to = rreq-\u003ecollected_to;\n \n \tif (rreq-\u003ecleaned_to \u003e= rreq-\u003ecollected_to)\n \t\treturn;\n@@ -179,7 +179,7 @@ static void netfs_read_unlock_folios(struct netfs_io_request *rreq,\n \n \tfor (;;) {\n \t\tstruct folio *folio;\n-\t\tunsigned long long fpos, fend;\n+\t\tuoff_t fpos, fend;\n \t\tsize_t fsize;\n \n \t\tfolio = folioq_folio(folioq, slot);\n@@ -192,7 +192,7 @@ static void netfs_read_unlock_folios(struct netfs_io_request *rreq,\n \t\tfpos = folio_pos(folio);\n \t\tfend = fpos + fsize;\n \n-\t\ttrace_netfs_collect_folio(rreq, folio, fend, collected_to);\n+\t\ttrace_netfs_collect_folio(rreq, folio);\n \n \t\t/* Unlock any folio we've transferred all of. */\n \t\tif (collected_to \u003c fend)\n@@ -462,10 +462,8 @@ bool netfs_read_collection(struct netfs_io_request *rreq)\n \t/* We're done when the app thread has finished posting subreqs and the\n \t * queue is empty.\n \t */\n-\tif (!test_bit(NETFS_RREQ_ALL_QUEUED, \u0026rreq-\u003eflags))\n+\tif (!netfs_are_all_subreqs_queued(rreq))\n \t\treturn false;\n-\tsmp_rmb(); /* Read ALL_QUEUED before subreq lists. */\n-\n \tif (!list_empty(\u0026stream-\u003esubrequests))\n \t\treturn false;\n \ndiff --git a/fs/netfs/read_pgpriv2.c b/fs/netfs/read_pgpriv2.c\nindex a4b7bb88cbdb6..5280b606fda41 100644\n--- a/fs/netfs/read_pgpriv2.c\n+++ b/fs/netfs/read_pgpriv2.c\n@@ -20,7 +20,7 @@ static void netfs_pgpriv2_copy_folio(struct netfs_io_request *creq, struct folio\n {\n \tstruct netfs_io_stream *cache = \u0026creq-\u003eio_streams[1];\n \tsize_t fsize = folio_size(folio), flen = fsize;\n-\tloff_t fpos = folio_pos(folio), i_size;\n+\tuoff_t fpos = folio_pos(folio), i_size;\n \tbool to_eof = false;\n \n \t_enter(\"\");\n@@ -158,8 +158,7 @@ void netfs_pgpriv2_end_copy_to_cache(struct netfs_io_request *rreq)\n \t\treturn;\n \n \tnetfs_issue_write(creq, \u0026creq-\u003eio_streams[1]);\n-\tsmp_wmb(); /* Write lists before ALL_QUEUED. */\n-\tset_bit(NETFS_RREQ_ALL_QUEUED, \u0026creq-\u003eflags);\n+\tnetfs_all_subreqs_queued(creq);\n \ttrace_netfs_rreq(rreq, netfs_rreq_trace_end_copy_to_cache);\n \tif (list_empty_careful(\u0026creq-\u003eio_streams[1].subrequests))\n \t\tnetfs_wake_collector(creq);\n@@ -175,8 +174,8 @@ void netfs_pgpriv2_end_copy_to_cache(struct netfs_io_request *rreq)\n bool netfs_pgpriv2_unlock_copied_folios(struct netfs_io_request *creq)\n {\n \tstruct folio_queue *folioq = creq-\u003ebuffer.tail;\n-\tunsigned long long collected_to = creq-\u003ecollected_to;\n \tunsigned int slot = creq-\u003ebuffer.first_tail_slot;\n+\tuoff_t collected_to = creq-\u003ecollected_to;\n \tbool made_progress = false;\n \n \tif (slot \u003e= folioq_nr_slots(folioq)) {\n@@ -186,7 +185,7 @@ bool netfs_pgpriv2_unlock_copied_folios(struct netfs_io_request *creq)\n \n \tfor (;;) {\n \t\tstruct folio *folio;\n-\t\tunsigned long long fpos, fend;\n+\t\tuoff_t fpos, fend;\n \t\tsize_t fsize, flen;\n \n \t\tfolio = folioq_folio(folioq, slot);\n@@ -199,9 +198,9 @@ bool netfs_pgpriv2_unlock_copied_folios(struct netfs_io_request *creq)\n \t\tfsize = folio_size(folio);\n \t\tflen = fsize;\n \n-\t\tfend = min_t(unsigned long long, fpos + flen, creq-\u003ei_size);\n+\t\tfend = min_t(uoff_t, fpos + flen, creq-\u003ei_size);\n \n-\t\ttrace_netfs_collect_folio(creq, folio, fend, collected_to);\n+\t\ttrace_netfs_collect_folio(creq, folio);\n \n \t\t/* Unlock any folio we've transferred all of. */\n \t\tif (collected_to \u003c fend)\ndiff --git a/fs/netfs/read_retry.c b/fs/netfs/read_retry.c\nindex 4f6a36c6e214f..396a05432a7e9 100644\n--- a/fs/netfs/read_retry.c\n+++ b/fs/netfs/read_retry.c\n@@ -75,7 +75,7 @@ static void netfs_retry_read_subrequests(struct netfs_io_request *rreq)\n \tdo {\n \t\tstruct netfs_io_subrequest *from, *to, *tmp;\n \t\tstruct iov_iter source;\n-\t\tunsigned long long start, len;\n+\t\tuoff_t start, len;\n \t\tsize_t part;\n \t\tbool boundary = false, subreq_superfluous = false;\n \n@@ -195,12 +195,11 @@ static void netfs_retry_read_subrequests(struct netfs_io_request *rreq)\n \t\t * and insert them after.\n \t\t */\n \t\tdo {\n-\t\t\tsubreq = netfs_alloc_subrequest(rreq);\n+\t\t\tsubreq = netfs_alloc_subrequest(rreq, NETFS_DOWNLOAD_FROM_SERVER);\n \t\t\tif (!subreq) {\n \t\t\t\tsubreq = to;\n \t\t\t\tgoto abandon_after;\n \t\t\t}\n-\t\t\tsubreq-\u003esource\t\t= NETFS_DOWNLOAD_FROM_SERVER;\n \t\t\tsubreq-\u003estart\t\t= start;\n \t\t\tsubreq-\u003elen\t\t= len;\n \t\t\tsubreq-\u003estream_nr\t= stream-\u003estream_nr;\ndiff --git a/fs/netfs/read_single.c b/fs/netfs/read_single.c\nindex de67ac41548d1..81295c055cedb 100644\n--- a/fs/netfs/read_single.c\n+++ b/fs/netfs/read_single.c\n@@ -92,11 +92,10 @@ static int netfs_single_dispatch_read(struct netfs_io_request *rreq)\n \tstruct netfs_io_subrequest *subreq;\n \tint ret = 0;\n \n-\tsubreq = netfs_alloc_subrequest(rreq);\n+\tsubreq = netfs_alloc_subrequest(rreq, NETFS_SOURCE_UNKNOWN);\n \tif (!subreq)\n \t\treturn -ENOMEM;\n \n-\tsubreq-\u003esource\t= NETFS_SOURCE_UNKNOWN;\n \tsubreq-\u003estart\t= 0;\n \tsubreq-\u003elen\t= rreq-\u003elen;\n \tsubreq-\u003eio_iter\t= rreq-\u003ebuffer.iter;\n@@ -113,14 +112,12 @@ static int netfs_single_dispatch_read(struct netfs_io_request *rreq)\n \t\t\t\tgoto cancel;\n \t\t}\n \n-\t\tsmp_wmb(); /* Write lists before ALL_QUEUED. */\n-\t\tset_bit(NETFS_RREQ_ALL_QUEUED, \u0026rreq-\u003eflags);\n+\t\tnetfs_all_subreqs_queued(rreq);\n \t\trreq-\u003enetfs_ops-\u003eissue_read(subreq);\n \t\trreq-\u003esubmitted += subreq-\u003elen;\n \t\tbreak;\n \tcase NETFS_READ_FROM_CACHE:\n-\t\tsmp_wmb(); /* Write lists before ALL_QUEUED. */\n-\t\tset_bit(NETFS_RREQ_ALL_QUEUED, \u0026rreq-\u003eflags);\n+\t\tnetfs_all_subreqs_queued(rreq);\n \t\ttrace_netfs_sreq(subreq, netfs_sreq_trace_submit);\n \t\tnetfs_single_read_cache(rreq, subreq);\n \t\trreq-\u003esubmitted += subreq-\u003elen;\n@@ -136,8 +133,7 @@ static int netfs_single_dispatch_read(struct netfs_io_request *rreq)\n \treturn ret;\n cancel:\n \tnetfs_cancel_read(subreq, ret);\n-\tsmp_wmb(); /* Write lists before ALL_QUEUED. */\n-\tset_bit(NETFS_RREQ_ALL_QUEUED, \u0026rreq-\u003eflags);\n+\tnetfs_all_subreqs_queued(rreq);\n \tnetfs_wake_collector(rreq);\n \treturn ret;\n }\ndiff --git a/fs/netfs/stats.c b/fs/netfs/stats.c\nindex ab6b916addc44..9a607c4e62dda 100644\n--- a/fs/netfs/stats.c\n+++ b/fs/netfs/stats.c\n@@ -32,7 +32,6 @@ atomic_t netfs_n_rh_write_zskip;\n atomic_t netfs_n_rh_retry_read_req;\n atomic_t netfs_n_rh_retry_read_subreq;\n atomic_t netfs_n_wh_buffered_write;\n-atomic_t netfs_n_wh_writethrough;\n atomic_t netfs_n_wh_dio_write;\n atomic_t netfs_n_wh_writepages;\n atomic_t netfs_n_wh_copy_to_cache;\n@@ -58,9 +57,8 @@ int netfs_stats_show(struct seq_file *m, void *v)\n \t\t atomic_read(\u0026netfs_n_rh_read_single),\n \t\t atomic_read(\u0026netfs_n_rh_write_begin),\n \t\t atomic_read(\u0026netfs_n_rh_write_zskip));\n-\tseq_printf(m, \"Writes : BW=%u WT=%u DW=%u WP=%u 2C=%u\\n\",\n+\tseq_printf(m, \"Writes : BW=%u DW=%u WP=%u 2C=%u\\n\",\n \t\t atomic_read(\u0026netfs_n_wh_buffered_write),\n-\t\t atomic_read(\u0026netfs_n_wh_writethrough),\n \t\t atomic_read(\u0026netfs_n_wh_dio_write),\n \t\t atomic_read(\u0026netfs_n_wh_writepages),\n \t\t atomic_read(\u0026netfs_n_wh_copy_to_cache));\ndiff --git a/fs/netfs/write_collect.c b/fs/netfs/write_collect.c\nindex 210eb8f3958d7..6d99d4a6f7808 100644\n--- a/fs/netfs/write_collect.c\n+++ b/fs/netfs/write_collect.c\n@@ -56,7 +56,7 @@ static void netfs_dump_request(const struct netfs_io_request *rreq)\n */\n int netfs_folio_written_back(struct folio *folio)\n {\n-\tenum netfs_folio_trace why = netfs_folio_trace_clear;\n+\tenum netfs_folio_trace why = netfs_folio_trace_endwb;\n \tstruct inode *inode = folio_inode(folio);\n \tstruct netfs_inode *ictx = netfs_inode(inode);\n \tstruct netfs_folio *finfo;\n@@ -67,7 +67,7 @@ int netfs_folio_written_back(struct folio *folio)\n \t\t/* Streaming writes cannot be redirtied whilst under writeback,\n \t\t * so discard the streaming record.\n \t\t */\n-\t\tunsigned long long fend;\n+\t\tuoff_t fend;\n \n \t\tfend = folio_pos(folio) + finfo-\u003edirty_offset + finfo-\u003edirty_len;\n \t\tspin_lock(\u0026ictx-\u003einode.i_lock);\n@@ -79,13 +79,13 @@ int netfs_folio_written_back(struct folio *folio)\n \t\tgroup = finfo-\u003enetfs_group;\n \t\tgcount++;\n \t\tkfree(finfo);\n-\t\twhy = netfs_folio_trace_clear_s;\n+\t\twhy = netfs_folio_trace_endwb_s;\n \t\tgoto end_wb;\n \t}\n \n \tif ((group = netfs_folio_group(folio))) {\n \t\tif (group == NETFS_FOLIO_COPY_TO_CACHE) {\n-\t\t\twhy = netfs_folio_trace_clear_cc;\n+\t\t\twhy = netfs_folio_trace_endwb_cc;\n \t\t\tfolio_detach_private(folio);\n \t\t\tgoto end_wb;\n \t\t}\n@@ -98,7 +98,7 @@ int netfs_folio_written_back(struct folio *folio)\n \t\tif (!folio_test_dirty(folio)) {\n \t\t\tfolio_detach_private(folio);\n \t\t\tgcount++;\n-\t\t\twhy = netfs_folio_trace_clear_g;\n+\t\t\twhy = netfs_folio_trace_endwb_g;\n \t\t}\n \t}\n \n@@ -115,8 +115,8 @@ static void netfs_writeback_unlock_folios(struct netfs_io_request *wreq,\n \t\t\t\t\t unsigned int *notes)\n {\n \tstruct folio_queue *folioq = wreq-\u003ebuffer.tail;\n-\tunsigned long long collected_to = wreq-\u003ecollected_to;\n \tunsigned int slot = wreq-\u003ebuffer.first_tail_slot;\n+\tuoff_t collected_to = wreq-\u003ecollected_to;\n \n \tif (WARN_ON_ONCE(!folioq)) {\n \t\tpr_err(\"[!] Writeback unlock found empty rolling buffer!\\n\");\n@@ -140,7 +140,7 @@ static void netfs_writeback_unlock_folios(struct netfs_io_request *wreq,\n \tfor (;;) {\n \t\tstruct folio *folio;\n \t\tstruct netfs_folio *finfo;\n-\t\tunsigned long long fpos, fend;\n+\t\tuoff_t fpos, fend;\n \t\tsize_t fsize, flen;\n \n \t\tfolio = folioq_folio(folioq, slot);\n@@ -154,9 +154,9 @@ static void netfs_writeback_unlock_folios(struct netfs_io_request *wreq,\n \t\tfinfo = netfs_folio_info(folio);\n \t\tflen = finfo ? finfo-\u003edirty_offset + finfo-\u003edirty_len : fsize;\n \n-\t\tfend = min_t(unsigned long long, fpos + flen, wreq-\u003ei_size);\n+\t\tfend = min_t(uoff_t, fpos + flen, wreq-\u003ei_size);\n \n-\t\ttrace_netfs_collect_folio(wreq, folio, fend, collected_to);\n+\t\ttrace_netfs_collect_folio(wreq, folio);\n \n \t\t/* Unlock any folio we've transferred all of. */\n \t\tif (collected_to \u003c fend)\n@@ -201,8 +201,8 @@ static void netfs_collect_write_results(struct netfs_io_request *wreq)\n {\n \tstruct netfs_io_subrequest *front, *remove;\n \tstruct netfs_io_stream *stream;\n-\tunsigned long long collected_to, issued_to;\n \tunsigned int notes;\n+\tuoff_t collected_to, issued_to;\n \tint s;\n \n \t_enter(\"%llx-%llx\", wreq-\u003estart, wreq-\u003estart + wreq-\u003elen);\n@@ -214,7 +214,6 @@ static void netfs_collect_write_results(struct netfs_io_request *wreq)\n \tsmp_rmb();\n \tcollected_to = ULLONG_MAX;\n \tif (wreq-\u003eorigin == NETFS_WRITEBACK ||\n-\t wreq-\u003eorigin == NETFS_WRITETHROUGH ||\n \t wreq-\u003eorigin == NETFS_PGPRIV2_COPY_TO_CACHE)\n \t\tnotes = NEED_UNLOCK;\n \telse\n@@ -372,9 +371,8 @@ bool netfs_write_collection(struct netfs_io_request *wreq)\n \t/* We're done when the app thread has finished posting subreqs and all\n \t * the queues in all the streams are empty.\n \t */\n-\tif (!test_bit(NETFS_RREQ_ALL_QUEUED, \u0026wreq-\u003eflags))\n+\tif (!netfs_are_all_subreqs_queued(wreq))\n \t\treturn false;\n-\tsmp_rmb(); /* Read ALL_QUEUED before lists. */\n \n \ttransferred = LONG_MAX;\n \tfor (s = 0; s \u003c NR_IO_STREAMS; s++) {\n@@ -411,7 +409,6 @@ bool netfs_write_collection(struct netfs_io_request *wreq)\n \tswitch (wreq-\u003eorigin) {\n \tcase NETFS_WRITEBACK:\n \tcase NETFS_WRITEBACK_SINGLE:\n-\tcase NETFS_WRITETHROUGH:\n \t\tnetfs_wb_end(ictx);\n \t\tbreak;\n \tdefault:\ndiff --git a/fs/netfs/write_issue.c b/fs/netfs/write_issue.c\nindex 851f6f93ad45a..e7cb496f63246 100644\n--- a/fs/netfs/write_issue.c\n+++ b/fs/netfs/write_issue.c\n@@ -89,14 +89,13 @@ static void netfs_kill_dirty_pages(struct address_space *mapping,\n */\n struct netfs_io_request *netfs_create_write_req(struct address_space *mapping,\n \t\t\t\t\t\tstruct file *file,\n-\t\t\t\t\t\tloff_t start,\n+\t\t\t\t\t\tuoff_t start,\n \t\t\t\t\t\tenum netfs_io_origin origin)\n {\n \tstruct netfs_io_request *wreq;\n \tstruct netfs_inode *ictx;\n \tbool is_cacheable = (origin == NETFS_WRITEBACK ||\n \t\t\t origin == NETFS_WRITEBACK_SINGLE ||\n-\t\t\t origin == NETFS_WRITETHROUGH ||\n \t\t\t origin == NETFS_PGPRIV2_COPY_TO_CACHE);\n \n \twreq = netfs_alloc_request(mapping, file, start, 0, origin);\n@@ -156,7 +155,7 @@ EXPORT_SYMBOL(netfs_prepare_write_failed);\n */\n void netfs_prepare_write(struct netfs_io_request *wreq,\n \t\t\t struct netfs_io_stream *stream,\n-\t\t\t loff_t start)\n+\t\t\t uoff_t start)\n {\n \tstruct netfs_io_subrequest *subreq;\n \tstruct iov_iter *wreq_iter = \u0026wreq-\u003ebuffer.iter;\n@@ -169,10 +168,9 @@ void netfs_prepare_write(struct netfs_io_request *wreq,\n \t wreq_iter-\u003efolioq_slot \u003e= folioq_nr_slots(wreq_iter-\u003efolioq))\n \t\trolling_buffer_make_space(\u0026wreq-\u003ebuffer, wreq-\u003egfp);\n \n-\tsubreq = netfs_alloc_subrequest(wreq);\n+\tsubreq = netfs_alloc_subrequest(wreq, stream-\u003esource);\n \tif (!subreq)\n \t\treturn;\n-\tsubreq-\u003esource\t\t= stream-\u003esource;\n \tsubreq-\u003estart\t\t= start;\n \tsubreq-\u003estream_nr\t= stream-\u003estream_nr;\n \tsubreq-\u003eio_iter\t\t= *wreq_iter;\n@@ -279,7 +277,7 @@ void netfs_issue_write(struct netfs_io_request *wreq,\n */\n size_t netfs_advance_write(struct netfs_io_request *wreq,\n \t\t\t struct netfs_io_stream *stream,\n-\t\t\t loff_t start, size_t len, bool to_eof)\n+\t\t\t uoff_t start, size_t len, bool to_eof)\n {\n \tstruct netfs_io_subrequest *subreq = stream-\u003econstruct;\n \tsize_t part;\n@@ -330,7 +328,7 @@ static int netfs_write_folio(struct netfs_io_request *wreq,\n \tstruct netfs_folio *finfo;\n \tsize_t iter_off = 0;\n \tsize_t fsize = folio_size(folio), flen = fsize, foff = 0;\n-\tloff_t fpos = folio_pos(folio), i_size;\n+\tuoff_t fpos = folio_pos(folio), i_size;\n \tbool to_eof = false, streamw = false;\n \tbool debug = false;\n \n@@ -367,11 +365,7 @@ static int netfs_write_folio(struct netfs_io_request *wreq,\n \t\tstreamw = true;\n \t}\n \n-\tif (wreq-\u003eorigin == NETFS_WRITETHROUGH) {\n-\t\tto_eof = false;\n-\t\tif (flen \u003e i_size - fpos)\n-\t\t\tflen = i_size - fpos;\n-\t} else if (flen \u003e i_size - fpos) {\n+\tif (flen \u003e i_size - fpos) {\n \t\tflen = i_size - fpos;\n \t\tif (!streamw)\n \t\t\tfolio_zero_segment(folio, flen, fsize);\n@@ -525,8 +519,7 @@ static void netfs_end_issue_write(struct netfs_io_request *wreq)\n {\n \tbool needs_poke = true;\n \n-\tsmp_wmb(); /* Write subreq lists before ALL_QUEUED. */\n-\tset_bit(NETFS_RREQ_ALL_QUEUED, \u0026wreq-\u003eflags);\n+\tnetfs_all_subreqs_queued(wreq);\n \n \tfor (int s = 0; s \u003c NR_IO_STREAMS; s++) {\n \t\tstruct netfs_io_stream *stream = \u0026wreq-\u003eio_streams[s];\n@@ -613,103 +606,6 @@ int netfs_writepages(struct address_space *mapping,\n }\n EXPORT_SYMBOL(netfs_writepages);\n \n-/*\n- * Begin a write operation for writing through the pagecache.\n- */\n-struct netfs_io_request *netfs_begin_writethrough(struct kiocb *iocb, size_t len)\n-{\n-\tstruct netfs_io_request *wreq = NULL;\n-\tstruct netfs_inode *ictx = netfs_inode(file_inode(iocb-\u003eki_filp));\n-\n-\tnetfs_wb_begin(ictx, false);\n-\n-\twreq = netfs_create_write_req(iocb-\u003eki_filp-\u003ef_mapping, iocb-\u003eki_filp,\n-\t\t\t\t iocb-\u003eki_pos, NETFS_WRITETHROUGH);\n-\tif (IS_ERR(wreq)) {\n-\t\tnetfs_wb_end(ictx);\n-\t\treturn wreq;\n-\t}\n-\n-\twreq-\u003eio_streams[0].avail = true;\n-\t__set_bit(NETFS_RREQ_OFFLOAD_COLLECTION, \u0026wreq-\u003eflags);\n-\ttrace_netfs_write(wreq, netfs_write_trace_writethrough);\n-\treturn wreq;\n-}\n-\n-/*\n- * Advance the state of the write operation used when writing through the\n- * pagecache. Data has been copied into the pagecache that we need to append\n- * to the request. If we've added more than wsize then we need to create a new\n- * subrequest.\n- */\n-int netfs_advance_writethrough(struct netfs_io_request *wreq, struct writeback_control *wbc,\n-\t\t\t struct folio *folio, size_t copied, bool to_page_end,\n-\t\t\t struct folio **writethrough_cache)\n-{\n-\tint ret;\n-\n-\t_enter(\"R=%x ic=%zu ws=%u cp=%zu tp=%u\",\n-\t wreq-\u003edebug_id, wreq-\u003ebuffer.iter.count, wreq-\u003ewsize, copied, to_page_end);\n-\n-\t/* The folio is locked. */\n-\n-\tif (*writethrough_cache != folio) {\n-\t\tif (*writethrough_cache) {\n-\t\t\t/* Did the folio get moved? */\n-\t\t\tfolio_put(*writethrough_cache);\n-\t\t\t*writethrough_cache = NULL;\n-\t\t}\n-\t\t/* We can make multiple writes to the folio... */\n-\t\tif (wreq-\u003elen == 0)\n-\t\t\ttrace_netfs_folio(folio, netfs_folio_trace_wthru);\n-\t\telse\n-\t\t\ttrace_netfs_folio(folio, netfs_folio_trace_wthru_plus);\n-\t\t*writethrough_cache = folio;\n-\t\tfolio_get(folio);\n-\t}\n-\n-\twreq-\u003elen += copied;\n-\n-\tif (!to_page_end) {\n-\t\tfolio_mark_dirty(folio);\n-\t\tfolio_unlock(folio);\n-\t\treturn 0;\n-\t}\n-\n-\tret = netfs_write_folio(wreq, wbc, folio);\n-\tfolio_put(*writethrough_cache);\n-\t*writethrough_cache = NULL;\n-\twreq-\u003esubmitted = wreq-\u003elen;\n-\treturn ret;\n-}\n-\n-/*\n- * End a write operation used when writing through the pagecache.\n- */\n-ssize_t netfs_end_writethrough(struct netfs_io_request *wreq, struct writeback_control *wbc,\n-\t\t\t struct folio *writethrough_cache)\n-{\n-\tssize_t ret;\n-\n-\t_enter(\"R=%x\", wreq-\u003edebug_id);\n-\n-\tif (writethrough_cache) {\n-\t\tfolio_lock(writethrough_cache);\n-\t\tnetfs_write_folio(wreq, wbc, writethrough_cache);\n-\t\tfolio_put(writethrough_cache);\n-\t\twreq-\u003esubmitted = wreq-\u003elen;\n-\t}\n-\n-\tnetfs_end_issue_write(wreq);\n-\n-\tif (wreq-\u003eiocb)\n-\t\tret = -EIOCBQUEUED;\n-\telse\n-\t\tret = netfs_wait_for_write(wreq);\n-\tnetfs_put_request(wreq, netfs_rreq_trace_put_return);\n-\treturn ret;\n-}\n-\n /*\n * Write some of a pending folio data back to the server and/or the cache.\n */\n@@ -721,7 +617,7 @@ static int netfs_write_folio_single(struct netfs_io_request *wreq,\n \tstruct netfs_io_stream *stream;\n \tsize_t iter_off = 0;\n \tsize_t fsize = folio_size(folio), flen;\n-\tloff_t fpos = folio_pos(folio);\n+\tuoff_t fpos = folio_pos(folio);\n \tssize_t ret;\n \tbool to_eof = false;\n \tbool no_debug = false;\n@@ -891,8 +787,7 @@ int netfs_writeback_single(struct address_space *mapping,\n stop:\n \tfor (int s = 0; s \u003c NR_IO_STREAMS; s++)\n \t\tnetfs_issue_write(wreq, \u0026wreq-\u003eio_streams[s]);\n-\tsmp_wmb(); /* Write lists before ALL_QUEUED. */\n-\tset_bit(NETFS_RREQ_ALL_QUEUED, \u0026wreq-\u003eflags);\n+\tnetfs_all_subreqs_queued(wreq);\n \n \tnetfs_wake_collector(wreq);\n \ndiff --git a/fs/netfs/write_retry.c b/fs/netfs/write_retry.c\nindex 058bc7a166a59..d7d5348496fc8 100644\n--- a/fs/netfs/write_retry.c\n+++ b/fs/netfs/write_retry.c\n@@ -55,7 +55,7 @@ static void netfs_retry_write_stream(struct netfs_io_request *wreq,\n \tdo {\n \t\tstruct netfs_io_subrequest *subreq = NULL, *from, *to, *tmp;\n \t\tstruct iov_iter source;\n-\t\tunsigned long long start, len;\n+\t\tuoff_t start, len;\n \t\tsize_t part;\n \t\tbool boundary = false;\n \n@@ -149,8 +149,7 @@ static void netfs_retry_write_stream(struct netfs_io_request *wreq,\n \t\t * and insert them after.\n \t\t */\n \t\tdo {\n-\t\t\tsubreq = netfs_alloc_subrequest(wreq);\n-\t\t\tsubreq-\u003esource\t\t= to-\u003esource;\n+\t\t\tsubreq = netfs_alloc_subrequest(wreq, stream-\u003esource);\n \t\t\tsubreq-\u003estart\t\t= start;\n \t\t\tsubreq-\u003estream_nr\t= to-\u003estream_nr;\n \t\t\tsubreq-\u003eretry_count\t= 1;\ndiff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig\nindex 6bb30543eff00..e7862f35b72c8 100644\n--- a/fs/nfs/Kconfig\n+++ b/fs/nfs/Kconfig\n@@ -174,6 +174,7 @@ config NFS_FSCACHE\n \tbool \"Provide NFS client caching support\"\n \tdepends on NFS_FS\n \tselect NETFS_SUPPORT\n+\tselect NETFS_PGPRIV2\n \tselect FSCACHE\n \thelp\n \t Say Y here if you want NFS data to be cached locally on disc through\ndiff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h\nindex 4c91a019972b6..ee524c863fa9b 100644\n--- a/include/linux/fscache-cache.h\n+++ b/include/linux/fscache-cache.h\n@@ -67,7 +67,7 @@ struct fscache_cache_ops {\n \n \t/* Change the size of a data object */\n \tvoid (*resize_cookie)(struct netfs_cache_resources *cres,\n-\t\t\t loff_t new_size);\n+\t\t\t uoff_t new_size);\n \n \t/* Invalidate an object */\n \tbool (*invalidate_cookie)(struct fscache_cookie *cookie);\ndiff --git a/include/linux/fscache.h b/include/linux/fscache.h\nindex 58fdb9605425d..e19fca38382b9 100644\n--- a/include/linux/fscache.h\n+++ b/include/linux/fscache.h\n@@ -112,7 +112,7 @@ struct fscache_cookie {\n \tstruct list_head\t\tproc_link;\t/* Link in proc list */\n \tstruct list_head\t\tcommit_link;\t/* Link in commit queue */\n \tstruct work_struct\t\twork;\t\t/* Commit/relinq/withdraw work */\n-\tloff_t\t\t\t\tobject_size;\t/* Size of the netfs object */\n+\tuoff_t\t\t\t\tobject_size;\t/* Size of the netfs object */\n \tunsigned long\t\t\tunused_at;\t/* Time at which unused (jiffies) */\n \tunsigned long\t\t\tflags;\n #define FSCACHE_COOKIE_RELINQUISHED\t0\t\t/* T if cookie has been relinquished */\n@@ -163,22 +163,22 @@ extern struct fscache_cookie *__fscache_acquire_cookie(\n \tu8,\n \tconst void *, size_t,\n \tconst void *, size_t,\n-\tloff_t);\n+\tuoff_t);\n extern void __fscache_use_cookie(struct fscache_cookie *, bool);\n-extern void __fscache_unuse_cookie(struct fscache_cookie *, const void *, const loff_t *);\n+extern void __fscache_unuse_cookie(struct fscache_cookie *, const void *, const uoff_t *);\n extern void __fscache_relinquish_cookie(struct fscache_cookie *, bool);\n-extern void __fscache_resize_cookie(struct fscache_cookie *, loff_t);\n-extern void __fscache_invalidate(struct fscache_cookie *, const void *, loff_t, unsigned int);\n+extern void __fscache_resize_cookie(struct fscache_cookie *, uoff_t);\n+extern void __fscache_invalidate(struct fscache_cookie *, const void *, uoff_t, unsigned int);\n extern int __fscache_begin_read_operation(struct netfs_cache_resources *, struct fscache_cookie *);\n extern int __fscache_begin_write_operation(struct netfs_cache_resources *, struct fscache_cookie *);\n \n void __fscache_write_to_cache(struct fscache_cookie *cookie,\n \t\t\t struct address_space *mapping,\n-\t\t\t loff_t start, size_t len, loff_t i_size,\n+\t\t\t uoff_t start, size_t len, uoff_t i_size,\n \t\t\t netfs_io_terminated_t term_func,\n \t\t\t void *term_func_priv,\n \t\t\t bool using_pgpriv2, bool cond);\n-extern void __fscache_clear_page_bits(struct address_space *, loff_t, size_t);\n+extern void __fscache_clear_page_bits(struct address_space *, uoff_t, size_t);\n \n /**\n * fscache_acquire_volume - Register a volume as desiring caching services\n@@ -249,7 +249,7 @@ struct fscache_cookie *fscache_acquire_cookie(struct fscache_volume *volume,\n \t\t\t\t\t size_t index_key_len,\n \t\t\t\t\t const void *aux_data,\n \t\t\t\t\t size_t aux_data_len,\n-\t\t\t\t\t loff_t object_size)\n+\t\t\t\t\t uoff_t object_size)\n {\n \tif (!fscache_volume_valid(volume))\n \t\treturn NULL;\n@@ -286,7 +286,7 @@ static inline void fscache_use_cookie(struct fscache_cookie *cookie,\n */\n static inline void fscache_unuse_cookie(struct fscache_cookie *cookie,\n \t\t\t\t\tconst void *aux_data,\n-\t\t\t\t\tconst loff_t *object_size)\n+\t\t\t\t\tconst uoff_t *object_size)\n {\n \tif (fscache_cookie_valid(cookie))\n \t\t__fscache_unuse_cookie(cookie, aux_data, object_size);\n@@ -327,7 +327,7 @@ static inline void *fscache_get_aux(struct fscache_cookie *cookie)\n */\n static inline\n void fscache_update_aux(struct fscache_cookie *cookie,\n-\t\t\tconst void *aux_data, const loff_t *object_size)\n+\t\t\tconst void *aux_data, const uoff_t *object_size)\n {\n \tvoid *p = fscache_get_aux(cookie);\n \n@@ -343,7 +343,7 @@ extern atomic_t fscache_n_updates;\n \n static inline\n void __fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data,\n-\t\t\t const loff_t *object_size)\n+\t\t\t const uoff_t *object_size)\n {\n #ifdef CONFIG_FSCACHE_STATS\n \tatomic_inc(\u0026fscache_n_updates);\n@@ -369,7 +369,7 @@ void __fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data\n */\n static inline\n void fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data,\n-\t\t\t const loff_t *object_size)\n+\t\t\t const uoff_t *object_size)\n {\n \tif (fscache_cookie_enabled(cookie))\n \t\t__fscache_update_cookie(cookie, aux_data, object_size);\n@@ -386,7 +386,7 @@ void fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data,\n * description.\n */\n static inline\n-void fscache_resize_cookie(struct fscache_cookie *cookie, loff_t new_size)\n+void fscache_resize_cookie(struct fscache_cookie *cookie, uoff_t new_size)\n {\n \tif (fscache_cookie_enabled(cookie))\n \t\t__fscache_resize_cookie(cookie, new_size);\n@@ -413,7 +413,7 @@ void fscache_resize_cookie(struct fscache_cookie *cookie, loff_t new_size)\n */\n static inline\n void fscache_invalidate(struct fscache_cookie *cookie,\n-\t\t\tconst void *aux_data, loff_t size, unsigned int flags)\n+\t\t\tconst void *aux_data, uoff_t size, unsigned int flags)\n {\n \tif (fscache_cookie_enabled(cookie))\n \t\t__fscache_invalidate(cookie, aux_data, size, flags);\n@@ -502,7 +502,7 @@ static inline void fscache_end_operation(struct netfs_cache_resources *cres)\n */\n static inline\n int fscache_read(struct netfs_cache_resources *cres,\n-\t\t loff_t start_pos,\n+\t\t uoff_t start_pos,\n \t\t struct iov_iter *iter,\n \t\t enum netfs_read_from_hole read_hole,\n \t\t netfs_io_terminated_t term_func,\n@@ -561,7 +561,7 @@ int fscache_begin_write_operation(struct netfs_cache_resources *cres,\n */\n static inline\n int fscache_write(struct netfs_cache_resources *cres,\n-\t\t loff_t start_pos,\n+\t\t uoff_t start_pos,\n \t\t struct iov_iter *iter,\n \t\t netfs_io_terminated_t term_func,\n \t\t void *term_func_priv)\n@@ -581,7 +581,7 @@ int fscache_write(struct netfs_cache_resources *cres,\n * waiting.\n */\n static inline void fscache_clear_page_bits(struct address_space *mapping,\n-\t\t\t\t\t loff_t start, size_t len,\n+\t\t\t\t\t uoff_t start, size_t len,\n \t\t\t\t\t bool caching)\n {\n \tif (caching)\n@@ -615,7 +615,7 @@ static inline void fscache_clear_page_bits(struct address_space *mapping,\n */\n static inline void fscache_write_to_cache(struct fscache_cookie *cookie,\n \t\t\t\t\t struct address_space *mapping,\n-\t\t\t\t\t loff_t start, size_t len, loff_t i_size,\n+\t\t\t\t\t uoff_t start, size_t len, uoff_t i_size,\n \t\t\t\t\t netfs_io_terminated_t term_func,\n \t\t\t\t\t void *term_func_priv,\n \t\t\t\t\t bool using_pgpriv2, bool caching)\ndiff --git a/include/linux/netfs.h b/include/linux/netfs.h\nindex b4dd32863dd45..71fdd6ef43a7d 100644\n--- a/include/linux/netfs.h\n+++ b/include/linux/netfs.h\n@@ -62,8 +62,8 @@ struct netfs_inode {\n \tstruct fscache_cookie\t*cache;\n #endif\n \tstruct list_head\twb_queue;\t/* Queue of processes wanting to do writeback */\n-\tloff_t\t\t\t_remote_i_size;\t/* Size of the remote file */\n-\tloff_t\t\t\t_zero_point;\t/* Size after which we assume there's no data\n+\tuoff_t\t\t\t_remote_i_size;\t/* Size of the remote file */\n+\tuoff_t\t\t\t_zero_point;\t/* Size after which we assume there's no data\n \t\t\t\t\t\t * on the server */\n \tspinlock_t\t\tlock;\t\t/* Lock covering wb_queue */\n \tatomic_t\t\tio_count;\t/* Number of outstanding reqs */\n@@ -142,7 +142,7 @@ struct netfs_io_stream {\n \tvoid (*issue_write)(struct netfs_io_subrequest *subreq);\n \t/* Collection tracking */\n \tstruct list_head\tsubrequests;\t/* Contributory I/O operations */\n-\tunsigned long long\tcollected_to;\t/* Position we've collected results to */\n+\tuoff_t\t\t\tcollected_to;\t/* Position we've collected results to */\n \tsize_t\t\t\ttransferred;\t/* The amount transferred from this stream */\n \tunsigned short\t\terror;\t\t/* Aggregate error for the stream */\n \tenum netfs_io_source\tsource;\t\t/* Where to read from/write to */\n@@ -161,7 +161,8 @@ struct netfs_cache_resources {\n \tconst struct netfs_cache_ops\t*ops;\n \tvoid\t\t\t\t*cache_priv;\n \tvoid\t\t\t\t*cache_priv2;\n-\tunsigned int\t\t\tdebug_id;\t/* Cookie debug ID */\n+\tunsigned int\t\t\tcookie_id;\t/* Cache cookie debug ID */\n+\tunsigned int\t\t\tobject_id;\t/* Cache object debug ID */\n \tunsigned int\t\t\tinval_counter;\t/* object-\u003einval_counter at begin_op */\n };\n \n@@ -177,7 +178,7 @@ struct netfs_io_subrequest {\n \tstruct work_struct\twork;\n \tstruct list_head\trreq_link;\t/* Link in rreq-\u003esubrequests */\n \tstruct iov_iter\t\tio_iter;\t/* Iterator for this subrequest */\n-\tunsigned long long\tstart;\t\t/* Where to start the I/O */\n+\tuoff_t\t\t\tstart;\t\t/* Where to start the I/O */\n \tsize_t\t\t\tlen;\t\t/* Size of the I/O */\n \tsize_t\t\t\ttransferred;\t/* Amount of data transferred */\n \trefcount_t\t\tref;\n@@ -208,7 +209,6 @@ enum netfs_io_origin {\n \tNETFS_DIO_READ,\t\t\t/* This is a direct I/O read */\n \tNETFS_WRITEBACK,\t\t/* This write was triggered by writepages */\n \tNETFS_WRITEBACK_SINGLE,\t\t/* This monolithic write was triggered by writepages */\n-\tNETFS_WRITETHROUGH,\t\t/* This write was made by netfs_perform_write() */\n \tNETFS_UNBUFFERED_WRITE,\t\t/* This is an unbuffered write */\n \tNETFS_DIO_WRITE,\t\t/* This is a direct I/O write */\n \tNETFS_PGPRIV2_COPY_TO_CACHE,\t/* [DEPRECATED] This is writing read data to the cache */\n@@ -243,17 +243,17 @@ struct netfs_io_request {\n \tvoid\t\t\t*netfs_priv;\t/* Private data for the netfs */\n \tvoid\t\t\t*netfs_priv2;\t/* Private data for the netfs */\n \tstruct bio_vec\t\t*direct_bv;\t/* DIO buffer list (when handling iovec-iter) */\n-\tunsigned long long\tsubmitted;\t/* Amount submitted for I/O so far */\n-\tunsigned long long\tlen;\t\t/* Length of the request */\n+\tuoff_t\t\t\tsubmitted;\t/* Amount submitted for I/O so far */\n+\tuoff_t\t\t\tlen;\t\t/* Length of the request */\n \tsize_t\t\t\ttransferred;\t/* Amount to be indicated as transferred */\n \tsize_t\t\t\tprogress_at;\t/* Report read progress when hit this much read */\n \tlong\t\t\terror;\t\t/* 0 or error that occurred */\n-\tunsigned long long\ti_size;\t\t/* Size of the file */\n-\tunsigned long long\tstart;\t\t/* Start position */\n+\tuoff_t\t\t\ti_size;\t\t/* Size of the file */\n+\tuoff_t\t\t\tstart;\t\t/* Start position */\n \tatomic64_t\t\tissued_to;\t/* Write issuer folio cursor */\n-\tunsigned long long\tcollected_to;\t/* Point we've collected to */\n-\tunsigned long long\tcleaned_to;\t/* Position we've cleaned folios to */\n-\tunsigned long long\tabandon_to;\t/* Position to abandon folios to */\n+\tuoff_t\t\t\tcollected_to;\t/* Point we've collected to */\n+\tuoff_t\t\t\tcleaned_to;\t/* Position we've cleaned folios to */\n+\tuoff_t\t\t\tabandon_to;\t/* Position to abandon folios to */\n \tconst struct folio\t*no_unlock_folio; /* Don't unlock this folio after read */\n \tgfp_t\t\t\tgfp;\t\t/* GFP flags to use */\n \tunsigned int\t\tdirect_bv_count; /* Number of elements in direct_bv[] */\n@@ -279,8 +279,10 @@ struct netfs_io_request {\n #define NETFS_RREQ_UPLOAD_TO_SERVER\t11\t/* Need to write to the server */\n #define NETFS_RREQ_USE_IO_ITER\t\t12\t/* Use -\u003eio_iter rather than -\u003ei_pages */\n #define NETFS_RREQ_NEED_PUT_RA_REFS\t17\t/* Need to put the folio refs RA gave us */\n+#ifdef CONFIG_NETFS_PGPRIV2\n #define NETFS_RREQ_USE_PGPRIV2\t\t31\t/* [DEPRECATED] Use PG_private_2 to mark\n \t\t\t\t\t\t * write to cache on read */\n+#endif\n \tconst struct netfs_request_ops *netfs_ops;\n };\n \n@@ -299,12 +301,12 @@ struct netfs_request_ops {\n \tint (*prepare_read)(struct netfs_io_subrequest *subreq);\n \tvoid (*issue_read)(struct netfs_io_subrequest *subreq);\n \tbool (*is_still_valid)(struct netfs_io_request *rreq);\n-\tint (*check_write_begin)(struct file *file, loff_t pos, unsigned len,\n+\tint (*check_write_begin)(struct file *file, uoff_t pos, unsigned len,\n \t\t\t\t struct folio **foliop, void **_fsdata);\n \tvoid (*done)(struct netfs_io_request *rreq);\n \n \t/* Modification handling */\n-\tvoid (*update_i_size)(struct inode *inode, loff_t i_size);\n+\tvoid (*update_i_size)(struct inode *inode, uoff_t i_size);\n \tvoid (*post_modify)(struct inode *inode);\n \n \t/* Write request handling */\n@@ -332,7 +334,7 @@ struct netfs_cache_ops {\n \n \t/* Read data from the cache */\n \tint (*read)(struct netfs_cache_resources *cres,\n-\t\t loff_t start_pos,\n+\t\t uoff_t start_pos,\n \t\t struct iov_iter *iter,\n \t\t enum netfs_read_from_hole read_hole,\n \t\t netfs_io_terminated_t term_func,\n@@ -340,7 +342,7 @@ struct netfs_cache_ops {\n \n \t/* Write data to the cache */\n \tint (*write)(struct netfs_cache_resources *cres,\n-\t\t loff_t start_pos,\n+\t\t uoff_t start_pos,\n \t\t struct iov_iter *iter,\n \t\t netfs_io_terminated_t term_func,\n \t\t void *term_func_priv);\n@@ -350,15 +352,15 @@ struct netfs_cache_ops {\n \n \t/* Expand readahead request */\n \tvoid (*expand_readahead)(struct netfs_cache_resources *cres,\n-\t\t\t\t unsigned long long *_start,\n-\t\t\t\t unsigned long long *_len,\n-\t\t\t\t unsigned long long i_size);\n+\t\t\t\t uoff_t *_start,\n+\t\t\t\t uoff_t *_len,\n+\t\t\t\t uoff_t i_size);\n \n \t/* Prepare a read operation, shortening it to a cached/uncached\n \t * boundary as appropriate.\n \t */\n \tenum netfs_io_source (*prepare_read)(struct netfs_io_subrequest *subreq,\n-\t\t\t\t\t unsigned long long i_size);\n+\t\t\t\t\t uoff_t i_size);\n \n \t/* Prepare a write subrequest, working out if we're allowed to do it\n \t * and finding out the maximum amount of data to gather before\n@@ -371,15 +373,15 @@ struct netfs_cache_ops {\n \t * actually do.\n \t */\n \tint (*prepare_write)(struct netfs_cache_resources *cres,\n-\t\t\t loff_t *_start, size_t *_len, size_t upper_len,\n-\t\t\t loff_t i_size, bool no_space_allocated_yet);\n+\t\t\t uoff_t *_start, size_t *_len, size_t upper_len,\n+\t\t\t uoff_t i_size, bool no_space_allocated_yet);\n \n \t/* Query the occupancy of the cache in a region, returning where the\n \t * next chunk of data starts and how long it is.\n \t */\n \tint (*query_occupancy)(struct netfs_cache_resources *cres,\n-\t\t\t loff_t start, size_t len, size_t granularity,\n-\t\t\t loff_t *_data_start, size_t *_data_len);\n+\t\t\t uoff_t start, size_t len, size_t granularity,\n+\t\t\t uoff_t *_data_start, size_t *_data_len);\n };\n \n /* High-level read API. */\n@@ -410,7 +412,7 @@ struct readahead_control;\n void netfs_readahead(struct readahead_control *);\n int netfs_read_folio(struct file *, struct folio *);\n int netfs_write_begin(struct netfs_inode *, struct file *,\n-\t\t struct address_space *, loff_t pos, unsigned int len,\n+\t\t struct address_space *, uoff_t pos, unsigned int len,\n \t\t struct folio **, void **fsdata);\n int netfs_writepages(struct address_space *mapping,\n \t\t struct writeback_control *wbc);\n@@ -488,10 +490,10 @@ static inline struct netfs_inode *netfs_inode(struct inode *inode)\n * cmpxchg8b without the need of the lock prefix). For SMP compiles and 64bit\n * archs it makes no difference if preempt is enabled or not.\n */\n-static inline unsigned long long netfs_read_remote_i_size(const struct inode *inode)\n+static inline uoff_t netfs_read_remote_i_size(const struct inode *inode)\n {\n \tconst struct netfs_inode *ictx = container_of(inode, struct netfs_inode, inode);\n-\tunsigned long long remote_i_size;\n+\tuoff_t remote_i_size;\n \n #if BITS_PER_LONG==32 \u0026\u0026 defined(CONFIG_SMP)\n \tunsigned int seq;\n@@ -526,7 +528,7 @@ static inline unsigned long long netfs_read_remote_i_size(const struct inode *in\n * spinning forever.\n */\n static inline void netfs_write_remote_i_size(struct inode *inode,\n-\t\t\t\t\t unsigned long long remote_i_size)\n+\t\t\t\t\t uoff_t remote_i_size)\n {\n \tstruct netfs_inode *ictx = netfs_inode(inode);\n \n@@ -563,10 +565,10 @@ static inline void netfs_write_remote_i_size(struct inode *inode,\n * cmpxchg8b without the need of the lock prefix). For SMP compiles and 64bit\n * archs it makes no difference if preempt is enabled or not.\n */\n-static inline unsigned long long netfs_read_zero_point(const struct inode *inode)\n+static inline uoff_t netfs_read_zero_point(const struct inode *inode)\n {\n \tstruct netfs_inode *ictx = container_of(inode, struct netfs_inode, inode);\n-\tunsigned long long zero_point;\n+\tuoff_t zero_point;\n \n #if BITS_PER_LONG==32 \u0026\u0026 defined(CONFIG_SMP)\n \tunsigned int seq;\n@@ -601,7 +603,7 @@ static inline unsigned long long netfs_read_zero_point(const struct inode *inode\n * forever.\n */\n static inline void netfs_write_zero_point(struct inode *inode,\n-\t\t\t\t\t unsigned long long zero_point)\n+\t\t\t\t\t uoff_t zero_point)\n {\n \tstruct netfs_inode *ictx = netfs_inode(inode);\n \n@@ -642,9 +644,9 @@ static inline void netfs_write_zero_point(struct inode *inode,\n * archs it makes no difference if preempt is enabled or not.\n */\n static inline void netfs_read_sizes(const struct inode *inode,\n-\t\t\t\t unsigned long long *i_size,\n-\t\t\t\t unsigned long long *remote_i_size,\n-\t\t\t\t unsigned long long *zero_point)\n+\t\t\t\t uoff_t *i_size,\n+\t\t\t\t uoff_t *remote_i_size,\n+\t\t\t\t uoff_t *zero_point)\n {\n \tconst struct netfs_inode *ictx = container_of(inode, struct netfs_inode, inode);\n #if BITS_PER_LONG==32 \u0026\u0026 defined(CONFIG_SMP)\n@@ -690,9 +692,9 @@ static inline void netfs_read_sizes(const struct inode *inode,\n * forever.\n */\n static inline void netfs_write_sizes(struct inode *inode,\n-\t\t\t\t unsigned long long i_size,\n-\t\t\t\t unsigned long long remote_i_size,\n-\t\t\t\t unsigned long long zero_point)\n+\t\t\t\t uoff_t i_size,\n+\t\t\t\t uoff_t remote_i_size,\n+\t\t\t\t uoff_t zero_point)\n {\n \tstruct netfs_inode *ictx = netfs_inode(inode);\n \n@@ -760,7 +762,7 @@ static inline void netfs_inode_init(struct netfs_inode *ctx,\n * Inform the netfs lib that a file got resized so that it can adjust its state.\n */\n static inline void netfs_resize_file(struct netfs_inode *ictx,\n-\t\t\t\t unsigned long long new_i_size,\n+\t\t\t\t uoff_t new_i_size,\n \t\t\t\t bool changed_on_server)\n {\n #if BITS_PER_LONG==32 \u0026\u0026 defined(CONFIG_SMP)\ndiff --git a/include/trace/events/cachefiles.h b/include/trace/events/cachefiles.h\nindex e3101410e8b2d..1938d51a94594 100644\n--- a/include/trace/events/cachefiles.h\n+++ b/include/trace/events/cachefiles.h\n@@ -449,7 +449,7 @@ TRACE_EVENT(cachefiles_vol_coherency,\n \n TRACE_EVENT(cachefiles_prep_read,\n \t TP_PROTO(struct cachefiles_object *obj,\n-\t\t loff_t start,\n+\t\t uoff_t start,\n \t\t size_t len,\n \t\t unsigned short flags,\n \t\t enum netfs_io_source source,\n@@ -464,7 +464,7 @@ TRACE_EVENT(cachefiles_prep_read,\n \t\t __field(enum netfs_io_source,\tsource)\n \t\t __field(enum cachefiles_prepare_read_trace,\twhy)\n \t\t __field(size_t,\t\t\tlen)\n-\t\t __field(loff_t,\t\t\tstart)\n+\t\t __field(uoff_t,\t\t\tstart)\n \t\t __field(unsigned int,\t\tnetfs_inode)\n \t\t __field(unsigned int,\t\tcache_inode)\n \t\t\t ),\n@@ -492,16 +492,16 @@ TRACE_EVENT(cachefiles_prep_read,\n TRACE_EVENT(cachefiles_read,\n \t TP_PROTO(struct cachefiles_object *obj,\n \t\t struct inode *backer,\n-\t\t loff_t start,\n+\t\t uoff_t start,\n \t\t size_t len),\n \n \t TP_ARGS(obj, backer, start, len),\n \n \t TP_STRUCT__entry(\n-\t\t __field(unsigned int,\t\t\tobj)\n-\t\t __field(unsigned int,\t\t\tbacker)\n-\t\t __field(size_t,\t\t\t\tlen)\n-\t\t __field(loff_t,\t\t\t\tstart)\n+\t\t __field(unsigned int,\tobj)\n+\t\t __field(unsigned int,\tbacker)\n+\t\t __field(size_t,\t\tlen)\n+\t\t __field(uoff_t,\t\tstart)\n \t\t\t ),\n \n \t TP_fast_assign(\n@@ -521,16 +521,16 @@ TRACE_EVENT(cachefiles_read,\n TRACE_EVENT(cachefiles_write,\n \t TP_PROTO(struct cachefiles_object *obj,\n \t\t struct inode *backer,\n-\t\t loff_t start,\n+\t\t uoff_t start,\n \t\t size_t len),\n \n \t TP_ARGS(obj, backer, start, len),\n \n \t TP_STRUCT__entry(\n-\t\t __field(unsigned int,\t\t\tobj)\n-\t\t __field(unsigned int,\t\t\tbacker)\n-\t\t __field(size_t,\t\t\t\tlen)\n-\t\t __field(loff_t,\t\t\t\tstart)\n+\t\t __field(unsigned int,\tobj)\n+\t\t __field(unsigned int,\tbacker)\n+\t\t __field(size_t,\t\tlen)\n+\t\t __field(uoff_t,\t\tstart)\n \t\t\t ),\n \n \t TP_fast_assign(\n@@ -549,7 +549,7 @@ TRACE_EVENT(cachefiles_write,\n \n TRACE_EVENT(cachefiles_trunc,\n \t TP_PROTO(struct cachefiles_object *obj, struct inode *backer,\n-\t\t loff_t from, loff_t to, enum cachefiles_trunc_trace why),\n+\t\t uoff_t from, uoff_t to, enum cachefiles_trunc_trace why),\n \n \t TP_ARGS(obj, backer, from, to, why),\n \n@@ -557,8 +557,8 @@ TRACE_EVENT(cachefiles_trunc,\n \t\t __field(unsigned int,\t\t\tobj)\n \t\t __field(unsigned int,\t\t\tbacker)\n \t\t __field(enum cachefiles_trunc_trace,\twhy)\n-\t\t __field(loff_t,\t\t\t\tfrom)\n-\t\t __field(loff_t,\t\t\t\tto)\n+\t\t __field(uoff_t,\t\t\t\tfrom)\n+\t\t __field(uoff_t,\t\t\t\tto)\n \t\t\t ),\n \n \t TP_fast_assign(\ndiff --git a/include/trace/events/fscache.h b/include/trace/events/fscache.h\nindex f1a73aa83fbbf..8735d428ebd9b 100644\n--- a/include/trace/events/fscache.h\n+++ b/include/trace/events/fscache.h\n@@ -460,13 +460,13 @@ TRACE_EVENT(fscache_relinquish,\n \t );\n \n TRACE_EVENT(fscache_invalidate,\n-\t TP_PROTO(struct fscache_cookie *cookie, loff_t new_size),\n+\t TP_PROTO(struct fscache_cookie *cookie, uoff_t new_size),\n \n \t TP_ARGS(cookie, new_size),\n \n \t TP_STRUCT__entry(\n \t\t __field(unsigned int,\t\tcookie\t\t)\n-\t\t __field(loff_t,\t\t\tnew_size\t)\n+\t\t __field(uoff_t,\t\t\tnew_size\t)\n \t\t\t ),\n \n \t TP_fast_assign(\n@@ -479,14 +479,14 @@ TRACE_EVENT(fscache_invalidate,\n \t );\n \n TRACE_EVENT(fscache_resize,\n-\t TP_PROTO(struct fscache_cookie *cookie, loff_t new_size),\n+\t TP_PROTO(struct fscache_cookie *cookie, uoff_t new_size),\n \n \t TP_ARGS(cookie, new_size),\n \n \t TP_STRUCT__entry(\n \t\t __field(unsigned int,\t\tcookie\t\t)\n-\t\t __field(loff_t,\t\t\told_size\t)\n-\t\t __field(loff_t,\t\t\tnew_size\t)\n+\t\t __field(uoff_t,\t\t\told_size\t)\n+\t\t __field(uoff_t,\t\t\tnew_size\t)\n \t\t\t ),\n \n \t TP_fast_assign(\ndiff --git a/include/trace/events/netfs.h b/include/trace/events/netfs.h\nindex 3fec3e8f91c85..303309be253f2 100644\n--- a/include/trace/events/netfs.h\n+++ b/include/trace/events/netfs.h\n@@ -30,8 +30,7 @@\n \tEM(netfs_write_trace_dio_write,\t\t\"DIO-WRITE\")\t\\\n \tEM(netfs_write_trace_unbuffered_write,\t\"UNB-WRITE\")\t\\\n \tEM(netfs_write_trace_writeback,\t\t\"WRITEBACK\")\t\\\n-\tEM(netfs_write_trace_writeback_single,\t\"WB-SINGLE\") \\\n-\tE_(netfs_write_trace_writethrough,\t\"WRITETHRU\")\n+\tE_(netfs_write_trace_writeback_single,\t\"WB-SINGLE\")\n \n #define netfs_rreq_origins\t\t\t\t\t\\\n \tEM(NETFS_READAHEAD,\t\t\t\"RA\")\t\t\\\n@@ -43,12 +42,12 @@\n \tEM(NETFS_DIO_READ,\t\t\t\"DR\")\t\t\\\n \tEM(NETFS_WRITEBACK,\t\t\t\"WB\")\t\t\\\n \tEM(NETFS_WRITEBACK_SINGLE,\t\t\"W1\")\t\t\\\n-\tEM(NETFS_WRITETHROUGH,\t\t\t\"WT\")\t\t\\\n \tEM(NETFS_UNBUFFERED_WRITE,\t\t\"UW\")\t\t\\\n \tEM(NETFS_DIO_WRITE,\t\t\t\"DW\")\t\t\\\n \tE_(NETFS_PGPRIV2_COPY_TO_CACHE,\t\t\"2C\")\n \n #define netfs_rreq_traces\t\t\t\t\t\\\n+\tEM(netfs_rreq_trace_all_queued,\t\t\"ALL-Q \")\t\\\n \tEM(netfs_rreq_trace_assess,\t\t\"ASSESS \")\t\\\n \tEM(netfs_rreq_trace_collect,\t\t\"COLLECT\")\t\\\n \tEM(netfs_rreq_trace_complete,\t\t\"COMPLET\")\t\\\n@@ -194,11 +193,11 @@\n \tEM(netfs_folio_trace_alloc_buffer,\t\"alloc-buf\")\t\\\n \tEM(netfs_folio_trace_cancel_copy,\t\"cancel-copy\")\t\\\n \tEM(netfs_folio_trace_cancel_store,\t\"cancel-store\")\t\\\n-\tEM(netfs_folio_trace_clear,\t\t\"clear\")\t\\\n-\tEM(netfs_folio_trace_clear_cc,\t\t\"clear-cc\")\t\\\n-\tEM(netfs_folio_trace_clear_g,\t\t\"clear-g\")\t\\\n-\tEM(netfs_folio_trace_clear_s,\t\t\"clear-s\")\t\\\n \tEM(netfs_folio_trace_end_copy,\t\t\"end-copy\")\t\\\n+\tEM(netfs_folio_trace_endwb,\t\t\"endwb\")\t\\\n+\tEM(netfs_folio_trace_endwb_cc,\t\t\"endwb-cc\")\t\\\n+\tEM(netfs_folio_trace_endwb_g,\t\t\"endwb-g\")\t\\\n+\tEM(netfs_folio_trace_endwb_s,\t\t\"endwb-s\")\t\\\n \tEM(netfs_folio_trace_filled_gaps,\t\"filled-gaps\")\t\\\n \tEM(netfs_folio_trace_invalidate_all,\t\"inval-all\")\t\\\n \tEM(netfs_folio_trace_invalidate_front,\t\"inval-front\")\t\\\n@@ -223,9 +222,7 @@\n \tEM(netfs_folio_trace_sched_copy,\t\"sched-copy\")\t\\\n \tEM(netfs_folio_trace_store,\t\t\"store\")\t\\\n \tEM(netfs_folio_trace_store_copy,\t\"store-copy\")\t\\\n-\tEM(netfs_folio_trace_store_plus,\t\"store+\")\t\\\n-\tEM(netfs_folio_trace_wthru,\t\t\"wthru\")\t\\\n-\tE_(netfs_folio_trace_wthru_plus,\t\"wthru+\")\n+\tE_(netfs_folio_trace_store_plus,\t\"store+\")\n \n #define netfs_collect_contig_traces\t\t\t\t\\\n \tEM(netfs_contig_trace_collect,\t\t\"Collect\")\t\\\n@@ -301,7 +298,7 @@ netfs_folioq_traces;\n \n TRACE_EVENT(netfs_read,\n \t TP_PROTO(struct netfs_io_request *rreq,\n-\t\t loff_t start, size_t len,\n+\t\t uoff_t start, size_t len,\n \t\t enum netfs_read_trace what),\n \n \t TP_ARGS(rreq, start, len, what),\n@@ -309,8 +306,9 @@ TRACE_EVENT(netfs_read,\n \t TP_STRUCT__entry(\n \t\t __field(unsigned int,\t\trreq)\n \t\t __field(unsigned int,\t\tcookie)\n-\t\t __field(loff_t,\t\t\ti_size)\n-\t\t __field(loff_t,\t\t\tstart)\n+\t\t __field(unsigned int,\t\tobject)\n+\t\t __field(uoff_t,\t\t\ti_size)\n+\t\t __field(uoff_t,\t\t\tstart)\n \t\t __field(size_t,\t\t\tlen)\n \t\t __field(enum netfs_read_trace,\twhat)\n \t\t __field(u64,\t\t\tnetfs_inode)\n@@ -318,7 +316,8 @@ TRACE_EVENT(netfs_read,\n \n \t TP_fast_assign(\n \t\t __entry-\u003erreq\t= rreq-\u003edebug_id;\n-\t\t __entry-\u003ecookie\t= rreq-\u003ecache_resources.debug_id;\n+\t\t __entry-\u003ecookie\t= rreq-\u003ecache_resources.cookie_id;\n+\t\t __entry-\u003eobject\t= rreq-\u003ecache_resources.object_id;\n \t\t __entry-\u003ei_size\t= rreq-\u003ei_size;\n \t\t __entry-\u003estart\t= start;\n \t\t __entry-\u003elen\t= len;\n@@ -326,10 +325,10 @@ TRACE_EVENT(netfs_read,\n \t\t __entry-\u003enetfs_inode = rreq-\u003einode-\u003ei_ino;\n \t\t\t ),\n \n-\t TP_printk(\"R=%08x %s c=%08x ni=%llx s=%llx l=%zx sz=%llx\",\n+\t TP_printk(\"R=%08x %s c=%08x o=%08x ni=%llx s=%llx l=%zx sz=%llx\",\n \t\t __entry-\u003erreq,\n \t\t __print_symbolic(__entry-\u003ewhat, netfs_read_traces),\n-\t\t __entry-\u003ecookie,\n+\t\t __entry-\u003ecookie, __entry-\u003eobject,\n \t\t __entry-\u003enetfs_inode,\n \t\t __entry-\u003estart, __entry-\u003elen, __entry-\u003ei_size)\n \t );\n@@ -377,7 +376,7 @@ TRACE_EVENT(netfs_sreq,\n \t\t __field(u8,\t\t\t\tslot)\n \t\t __field(size_t,\t\t\tlen)\n \t\t __field(size_t,\t\t\ttransferred)\n-\t\t __field(loff_t,\t\t\tstart)\n+\t\t __field(uoff_t,\t\t\tstart)\n \t\t\t ),\n \n \t TP_fast_assign(\n@@ -418,7 +417,7 @@ TRACE_EVENT(netfs_failure,\n \t\t __field(enum netfs_failure,\t\twhat)\n \t\t __field(size_t,\t\t\tlen)\n \t\t __field(size_t,\t\t\ttransferred)\n-\t\t __field(loff_t,\t\t\tstart)\n+\t\t __field(uoff_t,\t\t\tstart)\n \t\t\t ),\n \n \t TP_fast_assign(\n@@ -501,6 +500,7 @@ TRACE_EVENT(netfs_folio,\n \t TP_STRUCT__entry(\n \t\t __field(u64,\t\t\tino)\n \t\t __field(pgoff_t,\t\t\tindex)\n+\t\t __field(unsigned long,\t\tpfn)\n \t\t __field(unsigned int,\t\tnr)\n \t\t __field(enum netfs_folio_trace,\twhy)\n \t\t\t ),\n@@ -511,9 +511,11 @@ TRACE_EVENT(netfs_folio,\n \t\t __entry-\u003ewhy = why;\n \t\t __entry-\u003eindex = folio-\u003eindex;\n \t\t __entry-\u003enr = folio_nr_pages(folio);\n+\t\t __entry-\u003epfn = folio_pfn(folio);\n \t\t\t ),\n \n-\t TP_printk(\"i=%05llx ix=%05lx-%05lx %s\",\n+\t TP_printk(\"p=%lx i=%05llx ix=%05lx-%05lx %s\",\n+\t\t __entry-\u003epfn,\n \t\t __entry-\u003eino, __entry-\u003eindex, __entry-\u003eindex + __entry-\u003enr - 1,\n \t\t __print_symbolic(__entry-\u003ewhy, netfs_folio_traces))\n \t );\n@@ -524,10 +526,10 @@ TRACE_EVENT(netfs_write_iter,\n \t TP_ARGS(iocb, from),\n \n \t TP_STRUCT__entry(\n-\t\t __field(unsigned long long,\t\tstart)\n-\t\t __field(size_t,\t\t\tlen)\n-\t\t __field(unsigned int,\t\tflags)\n-\t\t __field(unsigned int,\t\tino)\n+\t\t __field(uoff_t,\t\tstart)\n+\t\t __field(size_t,\t\tlen)\n+\t\t __field(unsigned int,\tflags)\n+\t\t __field(unsigned int,\tino)\n \t\t\t ),\n \n \t TP_fast_assign(\n@@ -550,27 +552,27 @@ TRACE_EVENT(netfs_write,\n \t TP_STRUCT__entry(\n \t\t __field(unsigned int,\t\twreq)\n \t\t __field(unsigned int,\t\tcookie)\n+\t\t __field(unsigned int,\t\tobject)\n \t\t __field(unsigned int,\t\tino)\n \t\t __field(enum netfs_write_trace,\twhat)\n-\t\t __field(unsigned long long,\t\tstart)\n-\t\t __field(unsigned long long,\t\tlen)\n+\t\t __field(uoff_t,\t\t\tstart)\n+\t\t __field(uoff_t,\t\t\tlen)\n \t\t\t ),\n \n \t TP_fast_assign(\n-\t\t struct netfs_inode *__ctx = netfs_inode(wreq-\u003einode);\n-\t\t struct fscache_cookie *__cookie = netfs_i_cookie(__ctx);\n \t\t __entry-\u003ewreq\t= wreq-\u003edebug_id;\n-\t\t __entry-\u003ecookie\t= __cookie ? __cookie-\u003edebug_id : 0;\n+\t\t __entry-\u003ecookie\t= wreq-\u003ecache_resources.cookie_id;\n+\t\t __entry-\u003eobject\t= wreq-\u003ecache_resources.object_id;\n \t\t __entry-\u003eino\t= wreq-\u003einode-\u003ei_ino;\n \t\t __entry-\u003ewhat\t= what;\n \t\t __entry-\u003estart\t= wreq-\u003estart;\n \t\t __entry-\u003elen\t= wreq-\u003elen;\n \t\t\t ),\n \n-\t TP_printk(\"R=%08x %s c=%08x i=%x by=%llx-%llx\",\n+\t TP_printk(\"R=%08x %s c=%08x o=%08x i=%x by=%llx-%llx\",\n \t\t __entry-\u003ewreq,\n \t\t __print_symbolic(__entry-\u003ewhat, netfs_write_traces),\n-\t\t __entry-\u003ecookie,\n+\t\t __entry-\u003ecookie, __entry-\u003eobject,\n \t\t __entry-\u003eino,\n \t\t __entry-\u003estart, __entry-\u003estart + __entry-\u003elen - 1)\n \t );\n@@ -582,25 +584,26 @@ TRACE_EVENT(netfs_copy2cache,\n \t TP_ARGS(rreq, creq),\n \n \t TP_STRUCT__entry(\n-\t\t __field(unsigned int,\t\trreq)\n-\t\t __field(unsigned int,\t\tcreq)\n-\t\t __field(unsigned int,\t\tcookie)\n-\t\t __field(unsigned int,\t\tino)\n+\t\t __field(unsigned int,\trreq)\n+\t\t __field(unsigned int,\tcreq)\n+\t\t __field(unsigned int,\tcookie)\n+\t\t __field(unsigned int,\tobject)\n+\t\t __field(unsigned int,\tino)\n \t\t\t ),\n \n \t TP_fast_assign(\n-\t\t struct netfs_inode *__ctx = netfs_inode(rreq-\u003einode);\n-\t\t struct fscache_cookie *__cookie = netfs_i_cookie(__ctx);\n \t\t __entry-\u003erreq\t= rreq-\u003edebug_id;\n \t\t __entry-\u003ecreq\t= creq-\u003edebug_id;\n-\t\t __entry-\u003ecookie\t= __cookie ? __cookie-\u003edebug_id : 0;\n+\t\t __entry-\u003ecookie\t= rreq-\u003ecache_resources.cookie_id;\n+\t\t __entry-\u003eobject\t= rreq-\u003ecache_resources.object_id;\n \t\t __entry-\u003eino\t= rreq-\u003einode-\u003ei_ino;\n \t\t\t ),\n \n-\t TP_printk(\"R=%08x CR=%08x c=%08x i=%x \",\n+\t TP_printk(\"R=%08x CR=%08x c=%08x o=%08x i=%x \",\n \t\t __entry-\u003erreq,\n \t\t __entry-\u003ecreq,\n \t\t __entry-\u003ecookie,\n+\t\t __entry-\u003eobject,\n \t\t __entry-\u003eino)\n \t );\n \n@@ -610,10 +613,10 @@ TRACE_EVENT(netfs_collect,\n \t TP_ARGS(wreq),\n \n \t TP_STRUCT__entry(\n-\t\t __field(unsigned int,\t\twreq)\n-\t\t __field(unsigned int,\t\tlen)\n-\t\t __field(unsigned long long,\t\ttransferred)\n-\t\t __field(unsigned long long,\t\tstart)\n+\t\t __field(unsigned int,\twreq)\n+\t\t __field(unsigned int,\tlen)\n+\t\t __field(uoff_t,\t\ttransferred)\n+\t\t __field(uoff_t,\t\tstart)\n \t\t\t ),\n \n \t TP_fast_assign(\n@@ -636,12 +639,12 @@ TRACE_EVENT(netfs_collect_sreq,\n \t TP_ARGS(wreq, subreq),\n \n \t TP_STRUCT__entry(\n-\t\t __field(unsigned int,\t\twreq)\n-\t\t __field(unsigned int,\t\tsubreq)\n-\t\t __field(unsigned int,\t\tstream)\n-\t\t __field(unsigned int,\t\tlen)\n-\t\t __field(unsigned int,\t\ttransferred)\n-\t\t __field(unsigned long long,\t\tstart)\n+\t\t __field(unsigned int,\twreq)\n+\t\t __field(unsigned int,\tsubreq)\n+\t\t __field(unsigned int,\tstream)\n+\t\t __field(unsigned int,\tlen)\n+\t\t __field(unsigned int,\ttransferred)\n+\t\t __field(uoff_t,\t\tstart)\n \t\t\t ),\n \n \t TP_fast_assign(\n@@ -660,37 +663,30 @@ TRACE_EVENT(netfs_collect_sreq,\n \n TRACE_EVENT(netfs_collect_folio,\n \t TP_PROTO(const struct netfs_io_request *wreq,\n-\t\t const struct folio *folio,\n-\t\t unsigned long long fend,\n-\t\t unsigned long long collected_to),\n+\t\t const struct folio *folio),\n \n-\t TP_ARGS(wreq, folio, fend, collected_to),\n+\t TP_ARGS(wreq, folio),\n \n \t TP_STRUCT__entry(\n \t\t __field(unsigned int,\twreq)\n \t\t __field(unsigned long,\tindex)\n-\t\t __field(unsigned long long,\tfend)\n-\t\t __field(unsigned long long,\tcleaned_to)\n-\t\t __field(unsigned long long,\tcollected_to)\n+\t\t __field(unsigned int,\tnr)\n \t\t\t ),\n \n \t TP_fast_assign(\n \t\t __entry-\u003ewreq\t= wreq-\u003edebug_id;\n \t\t __entry-\u003eindex\t= folio-\u003eindex;\n-\t\t __entry-\u003efend\t= fend;\n-\t\t __entry-\u003ecleaned_to\t= wreq-\u003ecleaned_to;\n-\t\t __entry-\u003ecollected_to = collected_to;\n+\t\t __entry-\u003enr\t\t= folio_nr_pages(folio);\n \t\t\t ),\n \n-\t TP_printk(\"R=%08x ix=%05lx r=%llx-%llx t=%llx/%llx\",\n+\t TP_printk(\"R=%08x ix=%05lx-%05lx\",\n \t\t __entry-\u003ewreq, __entry-\u003eindex,\n-\t\t (unsigned long long)__entry-\u003eindex * PAGE_SIZE, __entry-\u003efend,\n-\t\t __entry-\u003ecleaned_to, __entry-\u003ecollected_to)\n+\t\t __entry-\u003eindex + __entry-\u003enr - 1)\n \t );\n \n TRACE_EVENT(netfs_collect_state,\n \t TP_PROTO(const struct netfs_io_request *wreq,\n-\t\t unsigned long long collected_to,\n+\t\t uoff_t collected_to,\n \t\t unsigned int notes),\n \n \t TP_ARGS(wreq, collected_to, notes),\n@@ -698,8 +694,8 @@ TRACE_EVENT(netfs_collect_state,\n \t TP_STRUCT__entry(\n \t\t __field(unsigned int,\twreq)\n \t\t __field(unsigned int,\tnotes)\n-\t\t __field(unsigned long long,\tcollected_to)\n-\t\t __field(unsigned long long,\tcleaned_to)\n+\t\t __field(uoff_t,\t\tcollected_to)\n+\t\t __field(uoff_t,\t\tcleaned_to)\n \t\t\t ),\n \n \t TP_fast_assign(\n@@ -718,7 +714,7 @@ TRACE_EVENT(netfs_collect_state,\n TRACE_EVENT(netfs_collect_gap,\n \t TP_PROTO(const struct netfs_io_request *wreq,\n \t\t const struct netfs_io_stream *stream,\n-\t\t unsigned long long jump_to, char type),\n+\t\t uoff_t jump_to, char type),\n \n \t TP_ARGS(wreq, stream, jump_to, type),\n \n@@ -726,8 +722,8 @@ TRACE_EVENT(netfs_collect_gap,\n \t\t __field(unsigned int,\twreq)\n \t\t __field(unsigned char,\tstream)\n \t\t __field(unsigned char,\ttype)\n-\t\t __field(unsigned long long,\tfrom)\n-\t\t __field(unsigned long long,\tto)\n+\t\t __field(uoff_t,\t\tfrom)\n+\t\t __field(uoff_t,\t\tto)\n \t\t\t ),\n \n \t TP_fast_assign(\n@@ -752,8 +748,8 @@ TRACE_EVENT(netfs_collect_stream,\n \t TP_STRUCT__entry(\n \t\t __field(unsigned int,\twreq)\n \t\t __field(unsigned char,\tstream)\n-\t\t __field(unsigned long long,\tcollected_to)\n-\t\t __field(unsigned long long,\tissued_to)\n+\t\t __field(uoff_t,\t\tcollected_to)\n+\t\t __field(uoff_t,\t\tissued_to)\n \t\t\t ),\n \n \t TP_fast_assign(\n"
} |
| 2/1 | 2026/09/09 08:19 | agent | patch-evaluator |
0mModel:core Args: null Results: {
"EnableConfigs": [
"NETFS_SUPPORT",
"FSCACHE",
"CACHEFILES",
"NETFS_PGPRIV2",
"9P_FS",
"AFS_FS",
"CEPH_FS",
"NFS_FSCACHE"
],
"FocusSymbols": [
"netfs_perform_write",
"netfs_alloc_subrequest",
"netfs_writepages",
"netfs_write_collection",
"netfs_read_collection",
"netfs_folio_written_back",
"cachefiles_begin_operation",
"__cachefiles_prepare_write",
"__cachefiles_write"
],
"Reasoning": "The patch series significantly refactors the netfs and fscache subsystems by removing the writethrough write path from netfs_perform_write(), migrating offset/size parameters across netfs and cachefiles to uoff_t, introducing CONFIG_NETFS_PGPRIV2 for modularizing PG_private_2 cache write tracking, refactoring netfs_alloc_subrequest() source initialization, and altering atomic subrequest queue tracking/wake-up logic. These modifications affect core file I/O, buffered write, read collection, and writeback paths in network filesystems (9p, afs, ceph, nfs) and local cachefiles.",
"WorthFuzzing": true
}Instruction: You are an expert Linux kernel maintainer and security engineer.
Your job is to review a provided patch series and evaluate whether it warrants fuzzing with syzkaller.
IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on internal assumptions. You must actively use your code access
tools to inspect the actual source code, callers, and surrounding context.
================================================================================
1. CORE TRIAGE PHILOSOPHY
================================================================================
The goal of patch fuzzing is to discover crashes, regressions, exposed latent bugs,
and newly triggered assertions introduced by the patch series.
- REACHABILITY IS THE PRIMARY GATE:
Fuzzing can only discover bugs in code that can actually execute in standard virtualized
environments (GCE or QEMU, utilizing software-emulated devices like USB gadgets, netdev, tun/tap).
If the modified code is structurally unreachable (see Section 2), it MUST NOT be fuzzed,
regardless of whether it adds assertions or complex logic.
- DO NOT BLINDLY TRUST "NO FUNCTIONAL CHANGE" (NFCI) OR "REFACTORING" CLAIMS:
Patch authors routinely label changes as "cleanups", "refactorings", or state
"No functional change intended". Do NOT take these claims at face value.
Code refactorings that rearrange logic, introduce helper functions, or alter state management
in core subsystems frequently introduce subtle semantic shifts or uncover latent kernel bugs.
If reachable executable code is modified or refactored, it MUST be fuzzed.
- NEW OR MODIFIED ASSERTIONS IN REACHABLE CODE MUST BE FUZZED:
When a patch introduces or modifies runtime checks or assertions (e.g., WARN_ON*, VM_WARN_ON*,
BUG_ON*, lockdep_assert*) in reachable code paths, it enforces new or stricter invariants.
Even if the author believes the invariant always holds, fuzzing is essential to verify whether
an unusual sequence of operations can violate it.
================================================================================
2. WHEN TO RETURN WorthFuzzing=false (NEGATIVE CRITERIA)
================================================================================
Return WorthFuzzing=false ONLY IF all modified code falls strictly into one or more of these categories:
- Non-kernel and non-executable changes:
* Modifications to Documentation/, comments, or spelling fixes.
* User-space directories, self-tests, samples, or scripts (e.g., tools/, samples/, scripts/, usr/)
that do not affect the compiled kernel image (vmlinux) or kernel modules.
* Purely decorative logging (e.g., message strings in pr_err, printk, dev_info) or tracepoints
that do not alter control flow or data structures.
* Build system or Kconfig changes that do not alter compiled C logic.
- Structurally unreachable hardware:
* Vendor-specific PCIe switches, SmartNICs, or GPU drivers (e.g., mlxsw, pds_core, qed,
ionic, amdgpu) requiring physical ASIC/PCIe cards not emulated in standard QEMU.
- Unreachable execution paths:
* Driver teardown callbacks (.remove, .shutdown, pci_unregister_driver) executed only during
physical PCI hot-unplug or manual sysfs driver unbinding.
* Code paths exclusive to architectures other than the target architecture.
================================================================================
3. WHEN TO RETURN WorthFuzzing=true (POSITIVE CRITERIA)
================================================================================
Return WorthFuzzing=true whenever the patch touches reachable executable code, including:
- Core Subsystems:
* Any logic modifications in memory management (mm/), synchronization/locking (kernel/locking/),
BPF, scheduler, core networking, VFS, or syscall handling.
- Refactorings and Code Cleanups:
* Any restructuring of reachable data structures, helper abstractions, or algorithm flows.
- Runtime Assertions and Defensive Checks:
* Any introduction or alteration of assertions (WARN_ON*, VM_WARN_ON*, BUG_ON*, etc.) in reachable paths.
- Reachable Drivers and Protocols:
* Drivers accessible via virtual buses (virtio, USB gadget, loopback, netlink, binder, sockets, etc.).
================================================================================
4. EXTRACTING FocusSymbols (PREVENTING DILUTION)
================================================================================
When WorthFuzzing=true, you must extract specific kernel functions into FocusSymbols to guide the fuzzer:
- AVOID UBIQUITOUS LIFECYCLE HOT-PATHS:
Do NOT list generic, ubiquitous functions called by almost every program in the corpus
(including, but not limited to: general memory allocators and deallocators, page fault
and trap handlers, or core synchronization primitives; this is not an exhaustive list).
Listing ubiquitous functions causes the fuzzer to classify thousands of unrelated tests as "focused",
which severely dilutes fuzzing effort away from the actual changes.
- TARGET SPECIFIC FEATURE LOGIC AND ENTRYPOINTS:
List functions that specifically implement the logic being added or altered, or direct API entrypoints
for the subsystem feature under review.
- HANDLING STATIC INLINE FUNCTIONS IN HEADERS (.h):
Compiler-inlined static functions (such as static inlines in mm/*.h or include/linux/*.h) lack
distinct symbol addresses in vmlinux and cannot be targeted directly by symbol coverage filters.
If the changes are primarily in static inline helpers, identify non-static, feature-specific caller
functions in .c files that exercise them (avoiding ubiquitous lifecycle wrappers).
================================================================================
5. IDENTIFYING EnableConfigs
================================================================================
Identify any specific CONFIG_ options required to properly compile and reach the modified code:
- Inspect Kconfig files and #ifdef guards; do not make assumptions.
- Check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed.
- Strip any 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4").
Prefer calling several tools at the same time to save round-trips.
Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.
Prompt: Target architecture: amd64
For your convenience, here is the diff of the changes:
commit f50aa0a56f8cd08bac1340311f5a577b64be7080
Author: syz-cluster <triage@syzkaller.com>
Date: Wed Sep 9 08:19:43 2026 +0000
syz-cluster: applied patch under review
diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c
index 1ac0b3dcc0778..2129fcb0f65c1 100644
--- a/fs/9p/vfs_addr.c
+++ b/fs/9p/vfs_addr.c
@@ -124,7 +124,6 @@ static int v9fs_init_request(struct netfs_io_request *rreq, struct file *file)
struct p9_fid *fid;
struct dentry *dentry;
bool writing = (rreq->origin == NETFS_READ_FOR_WRITE ||
- rreq->origin == NETFS_WRITETHROUGH ||
rreq->origin == NETFS_UNBUFFERED_WRITE ||
rreq->origin == NETFS_DIO_WRITE);
diff --git a/fs/afs/file.c b/fs/afs/file.c
index 0467742bfeee3..99987f6bbc36a 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -400,7 +400,6 @@ static int afs_init_request(struct netfs_io_request *rreq, struct file *file)
}
break;
case NETFS_WRITEBACK:
- case NETFS_WRITETHROUGH:
case NETFS_UNBUFFERED_WRITE:
case NETFS_DIO_WRITE:
if (S_ISREG(rreq->inode->i_mode))
@@ -413,7 +412,7 @@ static int afs_init_request(struct netfs_io_request *rreq, struct file *file)
return 0;
}
-static int afs_check_write_begin(struct file *file, loff_t pos, unsigned len,
+static int afs_check_write_begin(struct file *file, uoff_t pos, unsigned len,
struct folio **foliop, void **_fsdata)
{
struct afs_vnode *vnode = AFS_FS_I(file_inode(file));
@@ -451,7 +450,7 @@ void afs_set_i_size(struct afs_vnode *vnode, loff_t new_i_size)
fscache_update_cookie(afs_vnode_cache(vnode), NULL, &new_i_size);
}
-static void afs_update_i_size(struct inode *inode, loff_t new_i_size)
+static void afs_update_i_size(struct inode *inode, uoff_t new_i_size)
{
afs_set_i_size(AFS_FS_I(inode), new_i_size);
}
diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c
index 50a000310a8c5..a160d5c3e74c0 100644
--- a/fs/cachefiles/interface.c
+++ b/fs/cachefiles/interface.c
@@ -111,7 +111,7 @@ static int cachefiles_adjust_size(struct cachefiles_object *object)
struct iattr newattrs;
struct file *file = object->file;
uint64_t ni_size;
- loff_t oi_size;
+ uoff_t oi_size;
int ret;
ni_size = object->cookie->object_size;
@@ -225,11 +225,11 @@ static bool cachefiles_lookup_cookie(struct fscache_cookie *cookie)
* any unused granules.
*/
static bool cachefiles_shorten_object(struct cachefiles_object *object,
- struct file *file, loff_t new_size)
+ struct file *file, uoff_t new_size)
{
struct cachefiles_cache *cache = object->volume->cache;
struct inode *inode = file_inode(file);
- loff_t i_size, dio_size;
+ uoff_t i_size, dio_size;
int ret;
dio_size = round_up(new_size, CACHEFILES_DIO_BLOCK_SIZE);
@@ -271,14 +271,14 @@ static bool cachefiles_shorten_object(struct cachefiles_object *object,
* Resize the backing object.
*/
static void cachefiles_resize_cookie(struct netfs_cache_resources *cres,
- loff_t new_size)
+ uoff_t new_size)
{
struct cachefiles_object *object = cachefiles_cres_object(cres);
struct cachefiles_cache *cache = object->volume->cache;
struct fscache_cookie *cookie = object->cookie;
const struct cred *saved_cred;
struct file *file = cachefiles_cres_file(cres);
- loff_t old_size = cookie->object_size;
+ uoff_t old_size = cookie->object_size;
_enter("%llu->%llu", old_size, new_size);
diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h
index c93324e0f98c7..60bd801ada04f 100644
--- a/fs/cachefiles/internal.h
+++ b/fs/cachefiles/internal.h
@@ -203,11 +203,11 @@ extern bool cachefiles_begin_operation(struct netfs_cache_resources *cres,
enum fscache_want_state want_state);
extern int __cachefiles_prepare_write(struct cachefiles_object *object,
struct file *file,
- loff_t *_start, size_t *_len, size_t upper_len,
+ uoff_t *_start, size_t *_len, size_t upper_len,
bool no_space_allocated_yet);
extern int __cachefiles_write(struct cachefiles_object *object,
struct file *file,
- loff_t start_pos,
+ uoff_t start_pos,
struct iov_iter *iter,
netfs_io_terminated_t term_func,
void *term_func_priv);
diff --git a/fs/cachefiles/io.c b/fs/cachefiles/io.c
index 9540ec25b3cb6..e61e885784d69 100644
--- a/fs/cachefiles/io.c
+++ b/fs/cachefiles/io.c
@@ -19,7 +19,7 @@
struct cachefiles_kiocb {
struct kiocb iocb;
refcount_t ki_refcnt;
- loff_t start;
+ uoff_t start;
union {
size_t skipped;
size_t len;
@@ -73,7 +73,7 @@ static void cachefiles_read_complete(struct kiocb *iocb, long ret)
* Initiate a read from the cache.
*/
static int cachefiles_read(struct netfs_cache_resources *cres,
- loff_t start_pos,
+ uoff_t start_pos,
struct iov_iter *iter,
enum netfs_read_from_hole read_hole,
netfs_io_terminated_t term_func,
@@ -197,8 +197,8 @@ static int cachefiles_read(struct netfs_cache_resources *cres,
* of data starts and how long it is.
*/
static int cachefiles_query_occupancy(struct netfs_cache_resources *cres,
- loff_t start, size_t len, size_t granularity,
- loff_t *_data_start, size_t *_data_len)
+ uoff_t start, size_t len, size_t granularity,
+ uoff_t *_data_start, size_t *_data_len)
{
struct cachefiles_object *object;
struct file *file;
@@ -280,7 +280,7 @@ static void cachefiles_write_complete(struct kiocb *iocb, long ret)
*/
int __cachefiles_write(struct cachefiles_object *object,
struct file *file,
- loff_t start_pos,
+ uoff_t start_pos,
struct iov_iter *iter,
netfs_io_terminated_t term_func,
void *term_func_priv)
@@ -357,7 +357,7 @@ int __cachefiles_write(struct cachefiles_object *object,
}
static int cachefiles_write(struct netfs_cache_resources *cres,
- loff_t start_pos,
+ uoff_t start_pos,
struct iov_iter *iter,
netfs_io_terminated_t term_func,
void *term_func_priv)
@@ -377,7 +377,7 @@ static int cachefiles_write(struct netfs_cache_resources *cres,
static inline enum netfs_io_source
cachefiles_do_prepare_read(struct netfs_cache_resources *cres,
- loff_t start, size_t *_len, loff_t i_size,
+ uoff_t start, size_t *_len, loff_t i_size,
unsigned long *_flags, ino_t netfs_ino)
{
enum cachefiles_prepare_read_trace why;
@@ -483,7 +483,7 @@ cachefiles_do_prepare_read(struct netfs_cache_resources *cres,
* boundary as appropriate.
*/
static enum netfs_io_source cachefiles_prepare_read(struct netfs_io_subrequest *subreq,
- unsigned long long i_size)
+ uoff_t i_size)
{
return cachefiles_do_prepare_read(&subreq->rreq->cache_resources,
subreq->start, &subreq->len, i_size,
@@ -495,7 +495,7 @@ static enum netfs_io_source cachefiles_prepare_read(struct netfs_io_subrequest *
*/
int __cachefiles_prepare_write(struct cachefiles_object *object,
struct file *file,
- loff_t *_start, size_t *_len, size_t upper_len,
+ uoff_t *_start, size_t *_len, size_t upper_len,
bool no_space_allocated_yet)
{
struct cachefiles_cache *cache = object->volume->cache;
@@ -577,8 +577,8 @@ int __cachefiles_prepare_write(struct cachefiles_object *object,
}
static int cachefiles_prepare_write(struct netfs_cache_resources *cres,
- loff_t *_start, size_t *_len, size_t upper_len,
- loff_t i_size, bool no_space_allocated_yet)
+ uoff_t *_start, size_t *_len, size_t upper_len,
+ uoff_t i_size, bool no_space_allocated_yet)
{
struct cachefiles_object *object = cachefiles_cres_object(cres);
struct cachefiles_cache *cache = object->volume->cache;
@@ -628,7 +628,7 @@ static void cachefiles_issue_write(struct netfs_io_subrequest *subreq)
struct netfs_io_stream *stream = &wreq->io_streams[subreq->stream_nr];
const struct cred *saved_cred;
size_t off, pre, post, len = subreq->len;
- loff_t start = subreq->start;
+ uoff_t start = subreq->start;
int ret;
_enter("W=%x[%x] %llx-%llx",
@@ -721,6 +721,7 @@ bool cachefiles_begin_operation(struct netfs_cache_resources *cres,
if (!cachefiles_cres_file(cres)) {
cres->ops = &cachefiles_netfs_cache_ops;
+ cres->object_id = object->debug_id;
if (object->file) {
spin_lock(&object->lock);
if (!cres->cache_priv2 && object->file)
diff --git a/fs/ceph/Kconfig b/fs/ceph/Kconfig
index 3d64a316ca31d..aa6ccd7794d23 100644
--- a/fs/ceph/Kconfig
+++ b/fs/ceph/Kconfig
@@ -4,6 +4,7 @@ config CEPH_FS
depends on INET
select CEPH_LIB
select NETFS_SUPPORT
+ select NETFS_PGPRIV2
select FS_ENCRYPTION_ALGS if FS_ENCRYPTION
default n
help
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index ecf33b66610c8..6586f6c1dc734 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -65,7 +65,7 @@
(CONGESTION_ON_THRESH(congestion_kb) - \
(CONGESTION_ON_THRESH(congestion_kb) >> 2))
-static int ceph_netfs_check_write_begin(struct file *file, loff_t pos, unsigned int len,
+static int ceph_netfs_check_write_begin(struct file *file, uoff_t pos, unsigned int len,
struct folio **foliop, void **_fsdata);
static inline struct ceph_snap_context *page_snap_context(struct page *page)
@@ -1854,7 +1854,7 @@ ceph_find_incompatible(struct folio *folio)
return NULL;
}
-static int ceph_netfs_check_write_begin(struct file *file, loff_t pos, unsigned int len,
+static int ceph_netfs_check_write_begin(struct file *file, uoff_t pos, unsigned int len,
struct folio **foliop, void **_fsdata)
{
struct inode *inode = file_inode(file);
diff --git a/fs/netfs/Kconfig b/fs/netfs/Kconfig
index 7701c037c3283..d0e7b0971fa3f 100644
--- a/fs/netfs/Kconfig
+++ b/fs/netfs/Kconfig
@@ -22,6 +22,9 @@ config NETFS_STATS
between CPUs. On the other hand, the stats are very useful for
debugging purposes. Saying 'Y' here is recommended.
+config NETFS_PGPRIV2
+ bool
+
config NETFS_DEBUG
bool "Enable dynamic debugging netfslib and FS-Cache"
depends on NETFS_SUPPORT
diff --git a/fs/netfs/Makefile b/fs/netfs/Makefile
index b43188d64bd87..54834cde7e568 100644
--- a/fs/netfs/Makefile
+++ b/fs/netfs/Makefile
@@ -11,7 +11,6 @@ netfs-y := \
misc.o \
objects.o \
read_collect.o \
- read_pgpriv2.o \
read_retry.o \
read_single.o \
rolling_buffer.o \
@@ -19,6 +18,7 @@ netfs-y := \
write_issue.o \
write_retry.o
+netfs-$(CONFIG_NETFS_PGPRIV2) += read_pgpriv2.o
netfs-$(CONFIG_NETFS_STATS) += stats.o
netfs-$(CONFIG_FSCACHE) += \
diff --git a/fs/netfs/buffered_read.c b/fs/netfs/buffered_read.c
index 424df70a5c30f..68496e1a171f5 100644
--- a/fs/netfs/buffered_read.c
+++ b/fs/netfs/buffered_read.c
@@ -10,9 +10,9 @@
#include "internal.h"
static void netfs_cache_expand_readahead(struct netfs_io_request *rreq,
- unsigned long long *_start,
- unsigned long long *_len,
- unsigned long long i_size)
+ uoff_t *_start,
+ uoff_t *_len,
+ uoff_t i_size)
{
struct netfs_cache_resources *cres = &rreq->cache_resources;
@@ -139,7 +139,7 @@ static ssize_t netfs_prepare_read_iterator(struct netfs_io_subrequest *subreq)
static enum netfs_io_source netfs_cache_prepare_read(struct netfs_io_request *rreq,
struct netfs_io_subrequest *subreq,
- loff_t i_size)
+ uoff_t i_size)
{
struct netfs_cache_resources *cres = &rreq->cache_resources;
enum netfs_io_source source;
@@ -242,7 +242,7 @@ static void netfs_mark_copy_to_cache(struct netfs_io_request *rreq,
if (overlap > 0 && copy) {
folio = folioq_folio(*fq, *slot);
- if (unlikely(test_bit(NETFS_RREQ_USE_PGPRIV2, &rreq->flags))) {
+ if (netfs_using_pgpriv2(rreq)) {
if (!folio_test_private_2(folio))
folio_start_private_2(folio);
} else {
@@ -269,17 +269,17 @@ static void netfs_mark_copy_to_cache(struct netfs_io_request *rreq,
static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
{
struct folio_queue *fq = rreq->buffer.tail;
- unsigned long long start = rreq->start;
unsigned int offset = 0;
ssize_t size = rreq->len;
+ uoff_t start = rreq->start;
int ret = 0, slot = 0;
do {
struct netfs_io_subrequest *subreq;
- enum netfs_io_source source = NETFS_SOURCE_UNKNOWN;
+ enum netfs_io_source source;
ssize_t slice;
- subreq = netfs_alloc_subrequest(rreq);
+ subreq = netfs_alloc_subrequest(rreq, NETFS_SOURCE_UNKNOWN);
if (!subreq) {
ret = -ENOMEM;
break;
@@ -293,8 +293,8 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
source = netfs_cache_prepare_read(rreq, subreq, rreq->i_size);
subreq->source = source;
if (source == NETFS_DOWNLOAD_FROM_SERVER) {
- unsigned long long zero_point = netfs_read_zero_point(rreq->inode);
- unsigned long long zp = umin(zero_point, rreq->i_size);
+ uoff_t zero_point = netfs_read_zero_point(rreq->inode);
+ uoff_t zp = umin(zero_point, rreq->i_size);
size_t len = subreq->len;
if (unlikely(rreq->origin == NETFS_READ_SINGLE))
@@ -355,10 +355,8 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
}
start += slice;
size -= slice;
- if (size <= 0) {
- smp_wmb(); /* Write lists before ALL_QUEUED. */
- set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
- }
+ if (size <= 0)
+ netfs_all_subreqs_queued(rreq);
if (fq) {
/* See if the cache indicated this should be cached. */
@@ -378,8 +376,7 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
} while (size > 0);
if (unlikely(size > 0)) {
- smp_wmb(); /* Write lists before ALL_QUEUED. */
- set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
+ netfs_all_subreqs_queued(rreq);
netfs_wake_collector(rreq);
}
@@ -642,11 +639,11 @@ EXPORT_SYMBOL(netfs_read_folio);
* If any of these criteria are met, then zero out the unwritten parts
* of the folio and return true. Otherwise, return false.
*/
-static bool netfs_skip_folio_read(struct folio *folio, loff_t pos, size_t len,
+static bool netfs_skip_folio_read(struct folio *folio, uoff_t pos, size_t len,
bool always_fill)
{
struct inode *inode = folio_inode(folio);
- loff_t i_size = i_size_read(inode);
+ uoff_t i_size = i_size_read(inode);
size_t offset = offset_in_folio(folio, pos);
size_t plen = folio_size(folio);
@@ -711,7 +708,7 @@ static bool netfs_skip_folio_read(struct folio *folio, loff_t pos, size_t len,
*/
int netfs_write_begin(struct netfs_inode *ctx,
struct file *file, struct address_space *mapping,
- loff_t pos, unsigned int len, struct folio **_folio,
+ uoff_t pos, unsigned int len, struct folio **_folio,
void **_fsdata)
{
struct netfs_io_request *rreq;
@@ -807,7 +804,7 @@ int netfs_prefetch_for_write(struct file *file, struct folio *folio,
struct netfs_io_request *rreq;
struct address_space *mapping = folio->mapping;
struct netfs_inode *ctx = netfs_inode(mapping->host);
- unsigned long long start = folio_pos(folio);
+ uoff_t start = folio_pos(folio);
size_t flen = folio_size(folio);
int ret;
diff --git a/fs/netfs/buffered_write.c b/fs/netfs/buffered_write.c
index 2cdb68e6b16ff..ead22980075fe 100644
--- a/fs/netfs/buffered_write.c
+++ b/fs/netfs/buffered_write.c
@@ -17,7 +17,7 @@
* as possible to hold as much of the remaining length as possible in one go.
*/
static struct folio *netfs_grab_folio_for_write(struct address_space *mapping,
- loff_t pos, size_t part)
+ uoff_t pos, size_t part)
{
pgoff_t index = pos / PAGE_SIZE;
fgf_t fgp_flags = FGP_WRITEBEGIN;
@@ -35,9 +35,9 @@ static struct folio *netfs_grab_folio_for_write(struct address_space *mapping,
* the values actually are.
*/
void netfs_update_i_size(struct netfs_inode *ctx, struct inode *inode,
- loff_t pos, size_t copied)
+ uoff_t pos, size_t copied)
{
- loff_t i_size, end = pos + copied;
+ uoff_t i_size, end = pos + copied;
blkcnt_t add;
size_t gap;
@@ -91,50 +91,20 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter,
struct inode *inode = file_inode(file);
struct address_space *mapping = inode->i_mapping;
struct netfs_inode *ctx = netfs_inode(inode);
- struct writeback_control wbc = {
- .sync_mode = WB_SYNC_NONE,
- .for_sync = true,
- .nr_to_write = LONG_MAX,
- .range_start = iocb->ki_pos,
- .range_end = iocb->ki_pos + iter->count,
- };
- struct netfs_io_request *wreq = NULL;
- struct folio *folio = NULL, *writethrough = NULL;
+ struct folio *folio = NULL;
unsigned int bdp_flags = (iocb->ki_flags & IOCB_NOWAIT) ? BDP_ASYNC : 0;
- ssize_t written = 0, ret, ret2;
- loff_t pos = iocb->ki_pos;
+ ssize_t written = 0, ret;
+ uoff_t pos = iocb->ki_pos;
size_t max_chunk = mapping_max_folio_size(mapping);
bool maybe_trouble = false;
- if (unlikely(iocb->ki_flags & (IOCB_DSYNC | IOCB_SYNC))
- ) {
- wbc_attach_fdatawrite_inode(&wbc, mapping->host);
-
- ret = filemap_write_and_wait_range(mapping, pos, pos + iter->count);
- if (ret < 0) {
- wbc_detach_inode(&wbc);
- goto out;
- }
-
- wreq = netfs_begin_writethrough(iocb, iter->count);
- if (IS_ERR(wreq)) {
- wbc_detach_inode(&wbc);
- ret = PTR_ERR(wreq);
- wreq = NULL;
- goto out;
- }
- if (!is_sync_kiocb(iocb))
- wreq->iocb = iocb;
- netfs_stat(&netfs_n_wh_writethrough);
- } else {
- netfs_stat(&netfs_n_wh_buffered_write);
- }
+ netfs_stat(&netfs_n_wh_buffered_write);
do {
enum netfs_folio_trace trace;
struct netfs_folio *finfo;
struct netfs_group *group;
- unsigned long long fpos;
+ uoff_t fpos;
size_t flen;
size_t offset; /* Offset into pagecache folio */
size_t part; /* Bytes to write to folio */
@@ -390,15 +360,8 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter,
pos += copied;
written += copied;
- if (likely(!wreq)) {
- folio_mark_dirty(folio);
- folio_unlock(folio);
- } else {
- netfs_advance_writethrough(wreq, &wbc, folio, copied,
- offset + copied == flen,
- &writethrough);
- /* Folio unlocked */
- }
+ folio_mark_dirty(folio);
+ folio_unlock(folio);
retry:
folio_put(folio);
folio = NULL;
@@ -420,15 +383,6 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter,
ctx->ops->post_modify(inode);
}
- if (unlikely(wreq)) {
- ret2 = netfs_end_writethrough(wreq, &wbc, writethrough);
- wbc_detach_inode(&wbc);
- if (ret2 == -EIOCBQUEUED)
- return ret2;
- if (ret == 0 && ret2 < 0)
- ret = ret2;
- }
-
iocb->ki_pos += written;
_leave(" = %zd [%zd]", written, ret);
return written ? written : ret;
diff --git a/fs/netfs/direct_read.c b/fs/netfs/direct_read.c
index 6a8fb0d55e040..8c15f30797238 100644
--- a/fs/netfs/direct_read.c
+++ b/fs/netfs/direct_read.c
@@ -47,15 +47,15 @@ static void netfs_prepare_dio_read_iterator(struct netfs_io_subrequest *subreq)
*/
static void netfs_dispatch_unbuffered_reads(struct netfs_io_request *rreq)
{
- unsigned long long start = rreq->start;
ssize_t size = rreq->len;
+ uoff_t start = rreq->start;
int ret;
do {
struct netfs_io_subrequest *subreq;
ssize_t slice;
- subreq = netfs_alloc_subrequest(rreq);
+ subreq = netfs_alloc_subrequest(rreq, NETFS_DOWNLOAD_FROM_SERVER);
if (!subreq) {
/* Stash the error in the request if there's not
* already an error set.
@@ -64,7 +64,6 @@ static void netfs_dispatch_unbuffered_reads(struct netfs_io_request *rreq)
break;
}
- subreq->source = NETFS_DOWNLOAD_FROM_SERVER;
subreq->start = start;
subreq->len = size;
@@ -84,10 +83,8 @@ static void netfs_dispatch_unbuffered_reads(struct netfs_io_request *rreq)
size -= slice;
start += slice;
rreq->submitted += slice;
- if (size <= 0) {
- smp_wmb(); /* Write lists before ALL_QUEUED. */
- set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
- }
+ if (size <= 0)
+ netfs_all_subreqs_queued(rreq);
rreq->netfs_ops->issue_read(subreq);
@@ -99,8 +96,7 @@ static void netfs_dispatch_unbuffered_reads(struct netfs_io_request *rreq)
} while (size > 0);
if (unlikely(size > 0)) {
- smp_wmb(); /* Write lists before ALL_QUEUED. */
- set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
+ netfs_all_subreqs_queued(rreq);
netfs_wake_collector(rreq);
}
}
diff --git a/fs/netfs/direct_write.c b/fs/netfs/direct_write.c
index 2361277416c73..32200c10d2a45 100644
--- a/fs/netfs/direct_write.c
+++ b/fs/netfs/direct_write.c
@@ -225,9 +225,9 @@ ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov_iter *
struct netfs_group *netfs_group)
{
struct netfs_io_request *wreq;
- unsigned long long start = iocb->ki_pos;
- unsigned long long end = start + iov_iter_count(iter);
ssize_t ret, n;
+ uoff_t start = iocb->ki_pos;
+ uoff_t end = start + iov_iter_count(iter);
size_t len = iov_iter_count(iter);
bool async = !is_sync_kiocb(iocb);
@@ -336,8 +336,8 @@ ssize_t netfs_unbuffered_write_iter(struct kiocb *iocb, struct iov_iter *from)
struct inode *inode = mapping->host;
struct netfs_inode *ictx = netfs_inode(inode);
ssize_t ret;
- loff_t pos = iocb->ki_pos;
- unsigned long long end = pos + iov_iter_count(from) - 1;
+ uoff_t pos = iocb->ki_pos;
+ uoff_t end = pos + iov_iter_count(from) - 1;
_enter("%llx,%zx,%llx", pos, iov_iter_count(from), i_size_read(inode));
diff --git a/fs/netfs/fscache_cookie.c b/fs/netfs/fscache_cookie.c
index 3d56fc73435ff..5a226f9cbdeaa 100644
--- a/fs/netfs/fscache_cookie.c
+++ b/fs/netfs/fscache_cookie.c
@@ -327,7 +327,7 @@ static struct fscache_cookie *fscache_alloc_cookie(
u8 advice,
const void *index_key, size_t index_key_len,
const void *aux_data, size_t aux_data_len,
- loff_t object_size)
+ uoff_t object_size)
{
struct fscache_cookie *cookie;
@@ -452,7 +452,7 @@ struct fscache_cookie *__fscache_acquire_cookie(
u8 advice,
const void *index_key, size_t index_key_len,
const void *aux_data, size_t aux_data_len,
- loff_t object_size)
+ uoff_t object_size)
{
struct fscache_cookie *cookie;
@@ -663,7 +663,7 @@ static void fscache_unuse_cookie_locked(struct fscache_cookie *cookie)
* Stop using the cookie for I/O.
*/
void __fscache_unuse_cookie(struct fscache_cookie *cookie,
- const void *aux_data, const loff_t *object_size)
+ const void *aux_data, const uoff_t *object_size)
{
unsigned int debug_id = cookie->debug_id;
unsigned int r = refcount_read(&cookie->ref);
@@ -1049,7 +1049,7 @@ static void fscache_perform_invalidation(struct fscache_cookie *cookie)
* Invalidate an object.
*/
void __fscache_invalidate(struct fscache_cookie *cookie,
- const void *aux_data, loff_t new_size,
+ const void *aux_data, uoff_t new_size,
unsigned int flags)
{
bool is_caching;
diff --git a/fs/netfs/fscache_io.c b/fs/netfs/fscache_io.c
index 37f05b4d34699..056a2bae5d99a 100644
--- a/fs/netfs/fscache_io.c
+++ b/fs/netfs/fscache_io.c
@@ -79,7 +79,7 @@ static int fscache_begin_operation(struct netfs_cache_resources *cres,
cres->ops = NULL;
cres->cache_priv = cookie;
cres->cache_priv2 = NULL;
- cres->debug_id = cookie->debug_id;
+ cres->cookie_id = cookie->debug_id;
cres->inval_counter = cookie->inval_counter;
if (!fscache_begin_cookie_access(cookie, why)) {
@@ -162,7 +162,7 @@ EXPORT_SYMBOL(__fscache_begin_write_operation);
struct fscache_write_request {
struct netfs_cache_resources cache_resources;
struct address_space *mapping;
- loff_t start;
+ uoff_t start;
size_t len;
bool set_bits;
bool using_pgpriv2;
@@ -171,7 +171,7 @@ struct fscache_write_request {
};
void __fscache_clear_page_bits(struct address_space *mapping,
- loff_t start, size_t len)
+ uoff_t start, size_t len)
{
pgoff_t first = start / PAGE_SIZE;
pgoff_t last = (start + len - 1) / PAGE_SIZE;
@@ -208,7 +208,7 @@ static void fscache_wreq_done(void *priv, ssize_t transferred_or_error)
void __fscache_write_to_cache(struct fscache_cookie *cookie,
struct address_space *mapping,
- loff_t start, size_t len, loff_t i_size,
+ uoff_t start, size_t len, uoff_t i_size,
netfs_io_terminated_t term_func,
void *term_func_priv,
bool using_pgpriv2, bool cond)
@@ -267,7 +267,7 @@ EXPORT_SYMBOL(__fscache_write_to_cache);
/*
* Change the size of a backing object.
*/
-void __fscache_resize_cookie(struct fscache_cookie *cookie, loff_t new_size)
+void __fscache_resize_cookie(struct fscache_cookie *cookie, uoff_t new_size)
{
struct netfs_cache_resources cres;
diff --git a/fs/netfs/internal.h b/fs/netfs/internal.h
index c79c8e69d60ca..4891e6e3c5db6 100644
--- a/fs/netfs/internal.h
+++ b/fs/netfs/internal.h
@@ -33,7 +33,7 @@ int netfs_prefetch_for_write(struct file *file, struct folio *folio,
* buffered_write.c
*/
void netfs_update_i_size(struct netfs_inode *ctx, struct inode *inode,
- loff_t pos, size_t copied);
+ uoff_t pos, size_t copied);
/*
* main.c
@@ -86,13 +86,14 @@ void netfs_wait_for_put_ra_refs(struct netfs_io_request *rreq);
*/
struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,
struct file *file,
- loff_t start, size_t len,
+ uoff_t start, size_t len,
enum netfs_io_origin origin);
void netfs_get_request(struct netfs_io_request *rreq, enum netfs_rreq_ref_trace what);
void netfs_clear_subrequests(struct netfs_io_request *rreq);
void netfs_put_request(struct netfs_io_request *rreq, enum netfs_rreq_ref_trace what);
void netfs_put_failed_request(struct netfs_io_request *rreq);
-struct netfs_io_subrequest *netfs_alloc_subrequest(struct netfs_io_request *rreq);
+struct netfs_io_subrequest *netfs_alloc_subrequest(struct netfs_io_request *rreq,
+ enum netfs_io_source source);
static inline void netfs_see_request(struct netfs_io_request *rreq,
enum netfs_rreq_ref_trace what)
@@ -120,9 +121,37 @@ void netfs_cache_read_terminated(void *priv, ssize_t transferred_or_error);
/*
* read_pgpriv2.c
*/
+#ifdef CONFIG_NETFS_PGPRIV2
+int netfs_prepare_pgpriv2_write_buffer(struct netfs_io_subrequest *subreq,
+ unsigned int max_segs);
void netfs_pgpriv2_copy_to_cache(struct netfs_io_request *rreq, struct folio *folio);
void netfs_pgpriv2_end_copy_to_cache(struct netfs_io_request *rreq);
bool netfs_pgpriv2_unlock_copied_folios(struct netfs_io_request *wreq);
+static inline bool netfs_using_pgpriv2(const struct netfs_io_request *rreq)
+{
+ return unlikely(test_bit(NETFS_RREQ_USE_PGPRIV2, &rreq->flags));
+}
+#else
+static inline int netfs_prepare_pgpriv2_write_buffer(struct netfs_io_subrequest *subreq,
+ unsigned int max_segs)
+{
+ return -EIO;
+}
+static inline void netfs_pgpriv2_copy_to_cache(struct netfs_io_request *rreq, struct folio *folio)
+{
+}
+static inline void netfs_pgpriv2_end_copy_to_cache(struct netfs_io_request *rreq)
+{
+}
+static inline bool netfs_pgpriv2_unlock_copied_folios(struct netfs_io_request *wreq)
+{
+ return true;
+}
+static inline bool netfs_using_pgpriv2(const struct netfs_io_request *rreq)
+{
+ return false;
+}
+#endif
/*
* read_retry.c
@@ -157,7 +186,6 @@ extern atomic_t netfs_n_rh_write_zskip;
extern atomic_t netfs_n_rh_retry_read_req;
extern atomic_t netfs_n_rh_retry_read_subreq;
extern atomic_t netfs_n_wh_buffered_write;
-extern atomic_t netfs_n_wh_writethrough;
extern atomic_t netfs_n_wh_dio_write;
extern atomic_t netfs_n_wh_writepages;
extern atomic_t netfs_n_wh_copy_to_cache;
@@ -203,11 +231,11 @@ void netfs_write_collection_worker(struct work_struct *work);
*/
struct netfs_io_request *netfs_create_write_req(struct address_space *mapping,
struct file *file,
- loff_t start,
+ uoff_t start,
enum netfs_io_origin origin);
void netfs_prepare_write(struct netfs_io_request *wreq,
struct netfs_io_stream *stream,
- loff_t start);
+ uoff_t start);
void netfs_reissue_write(struct netfs_io_stream *stream,
struct netfs_io_subrequest *subreq,
struct iov_iter *source);
@@ -215,13 +243,7 @@ void netfs_issue_write(struct netfs_io_request *wreq,
struct netfs_io_stream *stream);
size_t netfs_advance_write(struct netfs_io_request *wreq,
struct netfs_io_stream *stream,
- loff_t start, size_t len, bool to_eof);
-struct netfs_io_request *netfs_begin_writethrough(struct kiocb *iocb, size_t len);
-int netfs_advance_writethrough(struct netfs_io_request *wreq, struct writeback_control *wbc,
- struct folio *folio, size_t copied, bool to_page_end,
- struct folio **writethrough_cache);
-ssize_t netfs_end_writethrough(struct netfs_io_request *wreq, struct writeback_control *wbc,
- struct folio *writethrough_cache);
+ uoff_t start, size_t len, bool to_eof);
/*
* write_retry.c
@@ -320,6 +342,26 @@ static inline bool netfs_check_subreq_in_progress(const struct netfs_io_subreque
return test_bit_acquire(NETFS_SREQ_IN_PROGRESS, &subreq->flags);
}
+/*
+ * Indicate that we've generated and queued all the subrequests we're going to.
+ */
+static inline void netfs_all_subreqs_queued(struct netfs_io_request *rreq)
+{
+ smp_wmb(); /* Write lists before ALL_QUEUED. */
+ set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
+ smp_mb__after_atomic();
+ trace_netfs_rreq(rreq, netfs_rreq_trace_all_queued);
+}
+
+/*
+ * Query if all subrequests are queued.
+ */
+static inline bool netfs_are_all_subreqs_queued(const struct netfs_io_request *rreq)
+{
+ /* Read lists after ALL_QUEUED. */
+ return test_bit_acquire(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
+}
+
/*
* fscache-cache.c
*/
diff --git a/fs/netfs/iterator.c b/fs/netfs/iterator.c
index b375567e0520e..eb1efb17f53aa 100644
--- a/fs/netfs/iterator.c
+++ b/fs/netfs/iterator.c
@@ -209,7 +209,7 @@ static size_t netfs_limit_xarray(const struct iov_iter *iter, size_t start_offse
{
struct folio *folio;
unsigned int nsegs = 0;
- loff_t pos = iter->xarray_start + iter->iov_offset;
+ uoff_t pos = iter->xarray_start + iter->iov_offset;
pgoff_t index = pos / PAGE_SIZE;
size_t span = 0, n = iter->count;
diff --git a/fs/netfs/main.c b/fs/netfs/main.c
index 927badf3989db..609e22e8f76a0 100644
--- a/fs/netfs/main.c
+++ b/fs/netfs/main.c
@@ -44,7 +44,6 @@ static const char *netfs_origins[nr__netfs_io_origin] = {
[NETFS_DIO_READ] = "DR",
[NETFS_WRITEBACK] = "WB",
[NETFS_WRITEBACK_SINGLE] = "W1",
- [NETFS_WRITETHROUGH] = "WT",
[NETFS_UNBUFFERED_WRITE] = "UW",
[NETFS_DIO_WRITE] = "DW",
[NETFS_PGPRIV2_COPY_TO_CACHE] = "2C",
diff --git a/fs/netfs/misc.c b/fs/netfs/misc.c
index f5c1c463f4ff7..a3cd76d584b8b 100644
--- a/fs/netfs/misc.c
+++ b/fs/netfs/misc.c
@@ -193,7 +193,7 @@ void netfs_clear_inode_writeback(struct inode *inode, const void *aux)
struct fscache_cookie *cookie = netfs_i_cookie(netfs_inode(inode));
if (inode_state_read_once(inode) & I_PINNING_NETFS_WB) {
- loff_t i_size = i_size_read(inode);
+ uoff_t i_size = i_size_read(inode);
fscache_unuse_cookie(cookie, aux, &i_size);
}
}
@@ -218,8 +218,8 @@ void netfs_invalidate_folio(struct folio *folio, size_t offset, size_t length)
_enter("{%lx},%zx,%zx", folio->index, offset, length);
if (offset == 0 && length == flen) {
- unsigned long long i_size, remote_i_size, zero_point;
- unsigned long long fpos = folio_pos(folio), end;
+ uoff_t i_size, remote_i_size, zero_point;
+ uoff_t fpos = folio_pos(folio), end;
netfs_read_sizes(inode, &i_size, &remote_i_size, &zero_point);
end = umin(fpos + flen, i_size);
@@ -305,7 +305,7 @@ bool netfs_release_folio(struct folio *folio, gfp_t gfp)
{
struct inode *inode = folio_inode(folio);
struct netfs_inode *ctx = netfs_inode(inode);
- unsigned long long i_size, remote_i_size, zero_point, end;
+ uoff_t i_size, remote_i_size, zero_point, end;
if (folio_test_dirty(folio))
return false;
@@ -424,7 +424,7 @@ static int netfs_collect_in_app(struct netfs_io_request *rreq,
need_collect = true;
break;
}
- if (subreq || !test_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags))
+ if (subreq || !netfs_are_all_subreqs_queued(rreq))
done = false;
}
diff --git a/fs/netfs/objects.c b/fs/netfs/objects.c
index 7f6a3e912602e..9c6ea718692a7 100644
--- a/fs/netfs/objects.c
+++ b/fs/netfs/objects.c
@@ -16,7 +16,7 @@ static void netfs_free_request(struct work_struct *work);
*/
struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,
struct file *file,
- loff_t start, size_t len,
+ uoff_t start, size_t len,
enum netfs_io_origin origin)
{
static atomic_t debug_ids;
@@ -207,7 +207,8 @@ void netfs_put_failed_request(struct netfs_io_request *rreq)
/*
* Allocate and partially initialise an I/O request structure.
*/
-struct netfs_io_subrequest *netfs_alloc_subrequest(struct netfs_io_request *rreq)
+struct netfs_io_subrequest *netfs_alloc_subrequest(struct netfs_io_request *rreq,
+ enum netfs_io_source source)
{
struct netfs_io_subrequest *subreq;
mempool_t *mempool = rreq->netfs_ops->subrequest_pool ?: &netfs_subrequest_pool;
@@ -224,6 +225,7 @@ struct netfs_io_subrequest *netfs_alloc_subrequest(struct netfs_io_request *rreq
INIT_WORK(&subreq->work, NULL);
INIT_LIST_HEAD(&subreq->rreq_link);
refcount_set(&subreq->ref, 2);
+ subreq->source = source;
subreq->rreq = rreq;
subreq->debug_index = atomic_inc_return(&rreq->subreq_counter);
netfs_get_request(rreq, netfs_rreq_trace_get_subreq);
diff --git a/fs/netfs/read_collect.c b/fs/netfs/read_collect.c
index 5cf22087d2439..cb97dedad170f 100644
--- a/fs/netfs/read_collect.c
+++ b/fs/netfs/read_collect.c
@@ -38,7 +38,7 @@ static void netfs_clear_unread(struct netfs_io_subrequest *subreq)
*/
void netfs_cancel_copy_to_cache(struct netfs_io_request *rreq, struct folio *folio)
{
- if (!test_bit(NETFS_RREQ_USE_PGPRIV2, &rreq->flags)) {
+ if (!netfs_using_pgpriv2(rreq)) {
if (folio_get_private(folio) == NETFS_FOLIO_COPY_TO_CACHE) {
folio_detach_private(folio);
trace_netfs_folio(folio, netfs_folio_trace_cancel_copy);
@@ -81,7 +81,7 @@ static void netfs_unlock_read_folio(struct netfs_io_request *rreq,
if (unlikely(test_bit(NETFS_RREQ_CANCEL_CACHING, &rreq->flags)))
netfs_cancel_copy_to_cache(rreq, folio);
- if (!test_bit(NETFS_RREQ_USE_PGPRIV2, &rreq->flags)) {
+ if (!netfs_using_pgpriv2(rreq)) {
if (netfs_folio_group(folio) == NETFS_FOLIO_COPY_TO_CACHE) {
trace_netfs_folio(folio, netfs_folio_trace_sched_copy);
folio_mark_dirty(folio);
@@ -153,8 +153,8 @@ static void netfs_read_unlock_folios(struct netfs_io_request *rreq,
unsigned int *notes)
{
struct folio_queue *folioq = rreq->buffer.tail;
- unsigned long long collected_to = rreq->collected_to;
unsigned int slot = rreq->buffer.first_tail_slot;
+ uoff_t collected_to = rreq->collected_to;
if (rreq->cleaned_to >= rreq->collected_to)
return;
@@ -179,7 +179,7 @@ static void netfs_read_unlock_folios(struct netfs_io_request *rreq,
for (;;) {
struct folio *folio;
- unsigned long long fpos, fend;
+ uoff_t fpos, fend;
size_t fsize;
folio = folioq_folio(folioq, slot);
@@ -192,7 +192,7 @@ static void netfs_read_unlock_folios(struct netfs_io_request *rreq,
fpos = folio_pos(folio);
fend = fpos + fsize;
- trace_netfs_collect_folio(rreq, folio, fend, collected_to);
+ trace_netfs_collect_folio(rreq, folio);
/* Unlock any folio we've transferred all of. */
if (collected_to < fend)
@@ -462,10 +462,8 @@ bool netfs_read_collection(struct netfs_io_request *rreq)
/* We're done when the app thread has finished posting subreqs and the
* queue is empty.
*/
- if (!test_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags))
+ if (!netfs_are_all_subreqs_queued(rreq))
return false;
- smp_rmb(); /* Read ALL_QUEUED before subreq lists. */
-
if (!list_empty(&stream->subrequests))
return false;
diff --git a/fs/netfs/read_pgpriv2.c b/fs/netfs/read_pgpriv2.c
index a4b7bb88cbdb6..5280b606fda41 100644
--- a/fs/netfs/read_pgpriv2.c
+++ b/fs/netfs/read_pgpriv2.c
@@ -20,7 +20,7 @@ static void netfs_pgpriv2_copy_folio(struct netfs_io_request *creq, struct folio
{
struct netfs_io_stream *cache = &creq->io_streams[1];
size_t fsize = folio_size(folio), flen = fsize;
- loff_t fpos = folio_pos(folio), i_size;
+ uoff_t fpos = folio_pos(folio), i_size;
bool to_eof = false;
_enter("");
@@ -158,8 +158,7 @@ void netfs_pgpriv2_end_copy_to_cache(struct netfs_io_request *rreq)
return;
netfs_issue_write(creq, &creq->io_streams[1]);
- smp_wmb(); /* Write lists before ALL_QUEUED. */
- set_bit(NETFS_RREQ_ALL_QUEUED, &creq->flags);
+ netfs_all_subreqs_queued(creq);
trace_netfs_rreq(rreq, netfs_rreq_trace_end_copy_to_cache);
if (list_empty_careful(&creq->io_streams[1].subrequests))
netfs_wake_collector(creq);
@@ -175,8 +174,8 @@ void netfs_pgpriv2_end_copy_to_cache(struct netfs_io_request *rreq)
bool netfs_pgpriv2_unlock_copied_folios(struct netfs_io_request *creq)
{
struct folio_queue *folioq = creq->buffer.tail;
- unsigned long long collected_to = creq->collected_to;
unsigned int slot = creq->buffer.first_tail_slot;
+ uoff_t collected_to = creq->collected_to;
bool made_progress = false;
if (slot >= folioq_nr_slots(folioq)) {
@@ -186,7 +185,7 @@ bool netfs_pgpriv2_unlock_copied_folios(struct netfs_io_request *creq)
for (;;) {
struct folio *folio;
- unsigned long long fpos, fend;
+ uoff_t fpos, fend;
size_t fsize, flen;
folio = folioq_folio(folioq, slot);
@@ -199,9 +198,9 @@ bool netfs_pgpriv2_unlock_copied_folios(struct netfs_io_request *creq)
fsize = folio_size(folio);
flen = fsize;
- fend = min_t(unsigned long long, fpos + flen, creq->i_size);
+ fend = min_t(uoff_t, fpos + flen, creq->i_size);
- trace_netfs_collect_folio(creq, folio, fend, collected_to);
+ trace_netfs_collect_folio(creq, folio);
/* Unlock any folio we've transferred all of. */
if (collected_to < fend)
diff --git a/fs/netfs/read_retry.c b/fs/netfs/read_retry.c
index 4f6a36c6e214f..396a05432a7e9 100644
--- a/fs/netfs/read_retry.c
+++ b/fs/netfs/read_retry.c
@@ -75,7 +75,7 @@ static void netfs_retry_read_subrequests(struct netfs_io_request *rreq)
do {
struct netfs_io_subrequest *from, *to, *tmp;
struct iov_iter source;
- unsigned long long start, len;
+ uoff_t start, len;
size_t part;
bool boundary = false, subreq_superfluous = false;
@@ -195,12 +195,11 @@ static void netfs_retry_read_subrequests(struct netfs_io_request *rreq)
* and insert them after.
*/
do {
- subreq = netfs_alloc_subrequest(rreq);
+ subreq = netfs_alloc_subrequest(rreq, NETFS_DOWNLOAD_FROM_SERVER);
if (!subreq) {
subreq = to;
goto abandon_after;
}
- subreq->source = NETFS_DOWNLOAD_FROM_SERVER;
subreq->start = start;
subreq->len = len;
subreq->stream_nr = stream->stream_nr;
diff --git a/fs/netfs/read_single.c b/fs/netfs/read_single.c
index de67ac41548d1..81295c055cedb 100644
--- a/fs/netfs/read_single.c
+++ b/fs/netfs/read_single.c
@@ -92,11 +92,10 @@ static int netfs_single_dispatch_read(struct netfs_io_request *rreq)
struct netfs_io_subrequest *subreq;
int ret = 0;
- subreq = netfs_alloc_subrequest(rreq);
+ subreq = netfs_alloc_subrequest(rreq, NETFS_SOURCE_UNKNOWN);
if (!subreq)
return -ENOMEM;
- subreq->source = NETFS_SOURCE_UNKNOWN;
subreq->start = 0;
subreq->len = rreq->len;
subreq->io_iter = rreq->buffer.iter;
@@ -113,14 +112,12 @@ static int netfs_single_dispatch_read(struct netfs_io_request *rreq)
goto cancel;
}
- smp_wmb(); /* Write lists before ALL_QUEUED. */
- set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
+ netfs_all_subreqs_queued(rreq);
rreq->netfs_ops->issue_read(subreq);
rreq->submitted += subreq->len;
break;
case NETFS_READ_FROM_CACHE:
- smp_wmb(); /* Write lists before ALL_QUEUED. */
- set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
+ netfs_all_subreqs_queued(rreq);
trace_netfs_sreq(subreq, netfs_sreq_trace_submit);
netfs_single_read_cache(rreq, subreq);
rreq->submitted += subreq->len;
@@ -136,8 +133,7 @@ static int netfs_single_dispatch_read(struct netfs_io_request *rreq)
return ret;
cancel:
netfs_cancel_read(subreq, ret);
- smp_wmb(); /* Write lists before ALL_QUEUED. */
- set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
+ netfs_all_subreqs_queued(rreq);
netfs_wake_collector(rreq);
return ret;
}
diff --git a/fs/netfs/stats.c b/fs/netfs/stats.c
index ab6b916addc44..9a607c4e62dda 100644
--- a/fs/netfs/stats.c
+++ b/fs/netfs/stats.c
@@ -32,7 +32,6 @@ atomic_t netfs_n_rh_write_zskip;
atomic_t netfs_n_rh_retry_read_req;
atomic_t netfs_n_rh_retry_read_subreq;
atomic_t netfs_n_wh_buffered_write;
-atomic_t netfs_n_wh_writethrough;
atomic_t netfs_n_wh_dio_write;
atomic_t netfs_n_wh_writepages;
atomic_t netfs_n_wh_copy_to_cache;
@@ -58,9 +57,8 @@ int netfs_stats_show(struct seq_file *m, void *v)
atomic_read(&netfs_n_rh_read_single),
atomic_read(&netfs_n_rh_write_begin),
atomic_read(&netfs_n_rh_write_zskip));
- seq_printf(m, "Writes : BW=%u WT=%u DW=%u WP=%u 2C=%u\n",
+ seq_printf(m, "Writes : BW=%u DW=%u WP=%u 2C=%u\n",
atomic_read(&netfs_n_wh_buffered_write),
- atomic_read(&netfs_n_wh_writethrough),
atomic_read(&netfs_n_wh_dio_write),
atomic_read(&netfs_n_wh_writepages),
atomic_read(&netfs_n_wh_copy_to_cache));
diff --git a/fs/netfs/write_collect.c b/fs/netfs/write_collect.c
index 210eb8f3958d7..6d99d4a6f7808 100644
--- a/fs/netfs/write_collect.c
+++ b/fs/netfs/write_collect.c
@@ -56,7 +56,7 @@ static void netfs_dump_request(const struct netfs_io_request *rreq)
*/
int netfs_folio_written_back(struct folio *folio)
{
- enum netfs_folio_trace why = netfs_folio_trace_clear;
+ enum netfs_folio_trace why = netfs_folio_trace_endwb;
struct inode *inode = folio_inode(folio);
struct netfs_inode *ictx = netfs_inode(inode);
struct netfs_folio *finfo;
@@ -67,7 +67,7 @@ int netfs_folio_written_back(struct folio *folio)
/* Streaming writes cannot be redirtied whilst under writeback,
* so discard the streaming record.
*/
- unsigned long long fend;
+ uoff_t fend;
fend = folio_pos(folio) + finfo->dirty_offset + finfo->dirty_len;
spin_lock(&ictx->inode.i_lock);
@@ -79,13 +79,13 @@ int netfs_folio_written_back(struct folio *folio)
group = finfo->netfs_group;
gcount++;
kfree(finfo);
- why = netfs_folio_trace_clear_s;
+ why = netfs_folio_trace_endwb_s;
goto end_wb;
}
if ((group = netfs_folio_group(folio))) {
if (group == NETFS_FOLIO_COPY_TO_CACHE) {
- why = netfs_folio_trace_clear_cc;
+ why = netfs_folio_trace_endwb_cc;
folio_detach_private(folio);
goto end_wb;
}
@@ -98,7 +98,7 @@ int netfs_folio_written_back(struct folio *folio)
if (!folio_test_dirty(folio)) {
folio_detach_private(folio);
gcount++;
- why = netfs_folio_trace_clear_g;
+ why = netfs_folio_trace_endwb_g;
}
}
@@ -115,8 +115,8 @@ static void netfs_writeback_unlock_folios(struct netfs_io_request *wreq,
unsigned int *notes)
{
struct folio_queue *folioq = wreq->buffer.tail;
- unsigned long long collected_to = wreq->collected_to;
unsigned int slot = wreq->buffer.first_tail_slot;
+ uoff_t collected_to = wreq->collected_to;
if (WARN_ON_ONCE(!folioq)) {
pr_err("[!] Writeback unlock found empty rolling buffer!\n");
@@ -140,7 +140,7 @@ static void netfs_writeback_unlock_folios(struct netfs_io_request *wreq,
for (;;) {
struct folio *folio;
struct netfs_folio *finfo;
- unsigned long long fpos, fend;
+ uoff_t fpos, fend;
size_t fsize, flen;
folio = folioq_folio(folioq, slot);
@@ -154,9 +154,9 @@ static void netfs_writeback_unlock_folios(struct netfs_io_request *wreq,
finfo = netfs_folio_info(folio);
flen = finfo ? finfo->dirty_offset + finfo->dirty_len : fsize;
- fend = min_t(unsigned long long, fpos + flen, wreq->i_size);
+ fend = min_t(uoff_t, fpos + flen, wreq->i_size);
- trace_netfs_collect_folio(wreq, folio, fend, collected_to);
+ trace_netfs_collect_folio(wreq, folio);
/* Unlock any folio we've transferred all of. */
if (collected_to < fend)
@@ -201,8 +201,8 @@ static void netfs_collect_write_results(struct netfs_io_request *wreq)
{
struct netfs_io_subrequest *front, *remove;
struct netfs_io_stream *stream;
- unsigned long long collected_to, issued_to;
unsigned int notes;
+ uoff_t collected_to, issued_to;
int s;
_enter("%llx-%llx", wreq->start, wreq->start + wreq->len);
@@ -214,7 +214,6 @@ static void netfs_collect_write_results(struct netfs_io_request *wreq)
smp_rmb();
collected_to = ULLONG_MAX;
if (wreq->origin == NETFS_WRITEBACK ||
- wreq->origin == NETFS_WRITETHROUGH ||
wreq->origin == NETFS_PGPRIV2_COPY_TO_CACHE)
notes = NEED_UNLOCK;
else
@@ -372,9 +371,8 @@ bool netfs_write_collection(struct netfs_io_request *wreq)
/* We're done when the app thread has finished posting subreqs and all
* the queues in all the streams are empty.
*/
- if (!test_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags))
+ if (!netfs_are_all_subreqs_queued(wreq))
return false;
- smp_rmb(); /* Read ALL_QUEUED before lists. */
transferred = LONG_MAX;
for (s = 0; s < NR_IO_STREAMS; s++) {
@@ -411,7 +409,6 @@ bool netfs_write_collection(struct netfs_io_request *wreq)
switch (wreq->origin) {
case NETFS_WRITEBACK:
case NETFS_WRITEBACK_SINGLE:
- case NETFS_WRITETHROUGH:
netfs_wb_end(ictx);
break;
default:
diff --git a/fs/netfs/write_issue.c b/fs/netfs/write_issue.c
index 851f6f93ad45a..e7cb496f63246 100644
--- a/fs/netfs/write_issue.c
+++ b/fs/netfs/write_issue.c
@@ -89,14 +89,13 @@ static void netfs_kill_dirty_pages(struct address_space *mapping,
*/
struct netfs_io_request *netfs_create_write_req(struct address_space *mapping,
struct file *file,
- loff_t start,
+ uoff_t start,
enum netfs_io_origin origin)
{
struct netfs_io_request *wreq;
struct netfs_inode *ictx;
bool is_cacheable = (origin == NETFS_WRITEBACK ||
origin == NETFS_WRITEBACK_SINGLE ||
- origin == NETFS_WRITETHROUGH ||
origin == NETFS_PGPRIV2_COPY_TO_CACHE);
wreq = netfs_alloc_request(mapping, file, start, 0, origin);
@@ -156,7 +155,7 @@ EXPORT_SYMBOL(netfs_prepare_write_failed);
*/
void netfs_prepare_write(struct netfs_io_request *wreq,
struct netfs_io_stream *stream,
- loff_t start)
+ uoff_t start)
{
struct netfs_io_subrequest *subreq;
struct iov_iter *wreq_iter = &wreq->buffer.iter;
@@ -169,10 +168,9 @@ void netfs_prepare_write(struct netfs_io_request *wreq,
wreq_iter->folioq_slot >= folioq_nr_slots(wreq_iter->folioq))
rolling_buffer_make_space(&wreq->buffer, wreq->gfp);
- subreq = netfs_alloc_subrequest(wreq);
+ subreq = netfs_alloc_subrequest(wreq, stream->source);
if (!subreq)
return;
- subreq->source = stream->source;
subreq->start = start;
subreq->stream_nr = stream->stream_nr;
subreq->io_iter = *wreq_iter;
@@ -279,7 +277,7 @@ void netfs_issue_write(struct netfs_io_request *wreq,
*/
size_t netfs_advance_write(struct netfs_io_request *wreq,
struct netfs_io_stream *stream,
- loff_t start, size_t len, bool to_eof)
+ uoff_t start, size_t len, bool to_eof)
{
struct netfs_io_subrequest *subreq = stream->construct;
size_t part;
@@ -330,7 +328,7 @@ static int netfs_write_folio(struct netfs_io_request *wreq,
struct netfs_folio *finfo;
size_t iter_off = 0;
size_t fsize = folio_size(folio), flen = fsize, foff = 0;
- loff_t fpos = folio_pos(folio), i_size;
+ uoff_t fpos = folio_pos(folio), i_size;
bool to_eof = false, streamw = false;
bool debug = false;
@@ -367,11 +365,7 @@ static int netfs_write_folio(struct netfs_io_request *wreq,
streamw = true;
}
- if (wreq->origin == NETFS_WRITETHROUGH) {
- to_eof = false;
- if (flen > i_size - fpos)
- flen = i_size - fpos;
- } else if (flen > i_size - fpos) {
+ if (flen > i_size - fpos) {
flen = i_size - fpos;
if (!streamw)
folio_zero_segment(folio, flen, fsize);
@@ -525,8 +519,7 @@ static void netfs_end_issue_write(struct netfs_io_request *wreq)
{
bool needs_poke = true;
- smp_wmb(); /* Write subreq lists before ALL_QUEUED. */
- set_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags);
+ netfs_all_subreqs_queued(wreq);
for (int s = 0; s < NR_IO_STREAMS; s++) {
struct netfs_io_stream *stream = &wreq->io_streams[s];
@@ -613,103 +606,6 @@ int netfs_writepages(struct address_space *mapping,
}
EXPORT_SYMBOL(netfs_writepages);
-/*
- * Begin a write operation for writing through the pagecache.
- */
-struct netfs_io_request *netfs_begin_writethrough(struct kiocb *iocb, size_t len)
-{
- struct netfs_io_request *wreq = NULL;
- struct netfs_inode *ictx = netfs_inode(file_inode(iocb->ki_filp));
-
- netfs_wb_begin(ictx, false);
-
- wreq = netfs_create_write_req(iocb->ki_filp->f_mapping, iocb->ki_filp,
- iocb->ki_pos, NETFS_WRITETHROUGH);
- if (IS_ERR(wreq)) {
- netfs_wb_end(ictx);
- return wreq;
- }
-
- wreq->io_streams[0].avail = true;
- __set_bit(NETFS_RREQ_OFFLOAD_COLLECTION, &wreq->flags);
- trace_netfs_write(wreq, netfs_write_trace_writethrough);
- return wreq;
-}
-
-/*
- * Advance the state of the write operation used when writing through the
- * pagecache. Data has been copied into the pagecache that we need to append
- * to the request. If we've added more than wsize then we need to create a new
- * subrequest.
- */
-int netfs_advance_writethrough(struct netfs_io_request *wreq, struct writeback_control *wbc,
- struct folio *folio, size_t copied, bool to_page_end,
- struct folio **writethrough_cache)
-{
- int ret;
-
- _enter("R=%x ic=%zu ws=%u cp=%zu tp=%u",
- wreq->debug_id, wreq->buffer.iter.count, wreq->wsize, copied, to_page_end);
-
- /* The folio is locked. */
-
- if (*writethrough_cache != folio) {
- if (*writethrough_cache) {
- /* Did the folio get moved? */
- folio_put(*writethrough_cache);
- *writethrough_cache = NULL;
- }
- /* We can make multiple writes to the folio... */
- if (wreq->len == 0)
- trace_netfs_folio(folio, netfs_folio_trace_wthru);
- else
- trace_netfs_folio(folio, netfs_folio_trace_wthru_plus);
- *writethrough_cache = folio;
- folio_get(folio);
- }
-
- wreq->len += copied;
-
- if (!to_page_end) {
- folio_mark_dirty(folio);
- folio_unlock(folio);
- return 0;
- }
-
- ret = netfs_write_folio(wreq, wbc, folio);
- folio_put(*writethrough_cache);
- *writethrough_cache = NULL;
- wreq->submitted = wreq->len;
- return ret;
-}
-
-/*
- * End a write operation used when writing through the pagecache.
- */
-ssize_t netfs_end_writethrough(struct netfs_io_request *wreq, struct writeback_control *wbc,
- struct folio *writethrough_cache)
-{
- ssize_t ret;
-
- _enter("R=%x", wreq->debug_id);
-
- if (writethrough_cache) {
- folio_lock(writethrough_cache);
- netfs_write_folio(wreq, wbc, writethrough_cache);
- folio_put(writethrough_cache);
- wreq->submitted = wreq->len;
- }
-
- netfs_end_issue_write(wreq);
-
- if (wreq->iocb)
- ret = -EIOCBQUEUED;
- else
- ret = netfs_wait_for_write(wreq);
- netfs_put_request(wreq, netfs_rreq_trace_put_return);
- return ret;
-}
-
/*
* Write some of a pending folio data back to the server and/or the cache.
*/
@@ -721,7 +617,7 @@ static int netfs_write_folio_single(struct netfs_io_request *wreq,
struct netfs_io_stream *stream;
size_t iter_off = 0;
size_t fsize = folio_size(folio), flen;
- loff_t fpos = folio_pos(folio);
+ uoff_t fpos = folio_pos(folio);
ssize_t ret;
bool to_eof = false;
bool no_debug = false;
@@ -891,8 +787,7 @@ int netfs_writeback_single(struct address_space *mapping,
stop:
for (int s = 0; s < NR_IO_STREAMS; s++)
netfs_issue_write(wreq, &wreq->io_streams[s]);
- smp_wmb(); /* Write lists before ALL_QUEUED. */
- set_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags);
+ netfs_all_subreqs_queued(wreq);
netfs_wake_collector(wreq);
diff --git a/fs/netfs/write_retry.c b/fs/netfs/write_retry.c
index 058bc7a166a59..d7d5348496fc8 100644
--- a/fs/netfs/write_retry.c
+++ b/fs/netfs/write_retry.c
@@ -55,7 +55,7 @@ static void netfs_retry_write_stream(struct netfs_io_request *wreq,
do {
struct netfs_io_subrequest *subreq = NULL, *from, *to, *tmp;
struct iov_iter source;
- unsigned long long start, len;
+ uoff_t start, len;
size_t part;
bool boundary = false;
@@ -149,8 +149,7 @@ static void netfs_retry_write_stream(struct netfs_io_request *wreq,
* and insert them after.
*/
do {
- subreq = netfs_alloc_subrequest(wreq);
- subreq->source = to->source;
+ subreq = netfs_alloc_subrequest(wreq, stream->source);
subreq->start = start;
subreq->stream_nr = to->stream_nr;
subreq->retry_count = 1;
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
index 6bb30543eff00..e7862f35b72c8 100644
--- a/fs/nfs/Kconfig
+++ b/fs/nfs/Kconfig
@@ -174,6 +174,7 @@ config NFS_FSCACHE
bool "Provide NFS client caching support"
depends on NFS_FS
select NETFS_SUPPORT
+ select NETFS_PGPRIV2
select FSCACHE
help
Say Y here if you want NFS data to be cached locally on disc through
diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h
index 4c91a019972b6..ee524c863fa9b 100644
--- a/include/linux/fscache-cache.h
+++ b/include/linux/fscache-cache.h
@@ -67,7 +67,7 @@ struct fscache_cache_ops {
/* Change the size of a data object */
void (*resize_cookie)(struct netfs_cache_resources *cres,
- loff_t new_size);
+ uoff_t new_size);
/* Invalidate an object */
bool (*invalidate_cookie)(struct fscache_cookie *cookie);
diff --git a/include/linux/fscache.h b/include/linux/fscache.h
index 58fdb9605425d..e19fca38382b9 100644
--- a/include/linux/fscache.h
+++ b/include/linux/fscache.h
@@ -112,7 +112,7 @@ struct fscache_cookie {
struct list_head proc_link; /* Link in proc list */
struct list_head commit_link; /* Link in commit queue */
struct work_struct work; /* Commit/relinq/withdraw work */
- loff_t object_size; /* Size of the netfs object */
+ uoff_t object_size; /* Size of the netfs object */
unsigned long unused_at; /* Time at which unused (jiffies) */
unsigned long flags;
#define FSCACHE_COOKIE_RELINQUISHED 0 /* T if cookie has been relinquished */
@@ -163,22 +163,22 @@ extern struct fscache_cookie *__fscache_acquire_cookie(
u8,
const void *, size_t,
const void *, size_t,
- loff_t);
+ uoff_t);
extern void __fscache_use_cookie(struct fscache_cookie *, bool);
-extern void __fscache_unuse_cookie(struct fscache_cookie *, const void *, const loff_t *);
+extern void __fscache_unuse_cookie(struct fscache_cookie *, const void *, const uoff_t *);
extern void __fscache_relinquish_cookie(struct fscache_cookie *, bool);
-extern void __fscache_resize_cookie(struct fscache_cookie *, loff_t);
-extern void __fscache_invalidate(struct fscache_cookie *, const void *, loff_t, unsigned int);
+extern void __fscache_resize_cookie(struct fscache_cookie *, uoff_t);
+extern void __fscache_invalidate(struct fscache_cookie *, const void *, uoff_t, unsigned int);
extern int __fscache_begin_read_operation(struct netfs_cache_resources *, struct fscache_cookie *);
extern int __fscache_begin_write_operation(struct netfs_cache_resources *, struct fscache_cookie *);
void __fscache_write_to_cache(struct fscache_cookie *cookie,
struct address_space *mapping,
- loff_t start, size_t len, loff_t i_size,
+ uoff_t start, size_t len, uoff_t i_size,
netfs_io_terminated_t term_func,
void *term_func_priv,
bool using_pgpriv2, bool cond);
-extern void __fscache_clear_page_bits(struct address_space *, loff_t, size_t);
+extern void __fscache_clear_page_bits(struct address_space *, uoff_t, size_t);
/**
* fscache_acquire_volume - Register a volume as desiring caching services
@@ -249,7 +249,7 @@ struct fscache_cookie *fscache_acquire_cookie(struct fscache_volume *volume,
size_t index_key_len,
const void *aux_data,
size_t aux_data_len,
- loff_t object_size)
+ uoff_t object_size)
{
if (!fscache_volume_valid(volume))
return NULL;
@@ -286,7 +286,7 @@ static inline void fscache_use_cookie(struct fscache_cookie *cookie,
*/
static inline void fscache_unuse_cookie(struct fscache_cookie *cookie,
const void *aux_data,
- const loff_t *object_size)
+ const uoff_t *object_size)
{
if (fscache_cookie_valid(cookie))
__fscache_unuse_cookie(cookie, aux_data, object_size);
@@ -327,7 +327,7 @@ static inline void *fscache_get_aux(struct fscache_cookie *cookie)
*/
static inline
void fscache_update_aux(struct fscache_cookie *cookie,
- const void *aux_data, const loff_t *object_size)
+ const void *aux_data, const uoff_t *object_size)
{
void *p = fscache_get_aux(cookie);
@@ -343,7 +343,7 @@ extern atomic_t fscache_n_updates;
static inline
void __fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data,
- const loff_t *object_size)
+ const uoff_t *object_size)
{
#ifdef CONFIG_FSCACHE_STATS
atomic_inc(&fscache_n_updates);
@@ -369,7 +369,7 @@ void __fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data
*/
static inline
void fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data,
- const loff_t *object_size)
+ const uoff_t *object_size)
{
if (fscache_cookie_enabled(cookie))
__fscache_update_cookie(cookie, aux_data, object_size);
@@ -386,7 +386,7 @@ void fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data,
* description.
*/
static inline
-void fscache_resize_cookie(struct fscache_cookie *cookie, loff_t new_size)
+void fscache_resize_cookie(struct fscache_cookie *cookie, uoff_t new_size)
{
if (fscache_cookie_enabled(cookie))
__fscache_resize_cookie(cookie, new_size);
@@ -413,7 +413,7 @@ void fscache_resize_cookie(struct fscache_cookie *cookie, loff_t new_size)
*/
static inline
void fscache_invalidate(struct fscache_cookie *cookie,
- const void *aux_data, loff_t size, unsigned int flags)
+ const void *aux_data, uoff_t size, unsigned int flags)
{
if (fscache_cookie_enabled(cookie))
__fscache_invalidate(cookie, aux_data, size, flags);
@@ -502,7 +502,7 @@ static inline void fscache_end_operation(struct netfs_cache_resources *cres)
*/
static inline
int fscache_read(struct netfs_cache_resources *cres,
- loff_t start_pos,
+ uoff_t start_pos,
struct iov_iter *iter,
enum netfs_read_from_hole read_hole,
netfs_io_terminated_t term_func,
@@ -561,7 +561,7 @@ int fscache_begin_write_operation(struct netfs_cache_resources *cres,
*/
static inline
int fscache_write(struct netfs_cache_resources *cres,
- loff_t start_pos,
+ uoff_t start_pos,
struct iov_iter *iter,
netfs_io_terminated_t term_func,
void *term_func_priv)
@@ -581,7 +581,7 @@ int fscache_write(struct netfs_cache_resources *cres,
* waiting.
*/
static inline void fscache_clear_page_bits(struct address_space *mapping,
- loff_t start, size_t len,
+ uoff_t start, size_t len,
bool caching)
{
if (caching)
@@ -615,7 +615,7 @@ static inline void fscache_clear_page_bits(struct address_space *mapping,
*/
static inline void fscache_write_to_cache(struct fscache_cookie *cookie,
struct address_space *mapping,
- loff_t start, size_t len, loff_t i_size,
+ uoff_t start, size_t len, uoff_t i_size,
netfs_io_terminated_t term_func,
void *term_func_priv,
bool using_pgpriv2, bool caching)
diff --git a/include/linux/netfs.h b/include/linux/netfs.h
index b4dd32863dd45..71fdd6ef43a7d 100644
--- a/include/linux/netfs.h
+++ b/include/linux/netfs.h
@@ -62,8 +62,8 @@ struct netfs_inode {
struct fscache_cookie *cache;
#endif
struct list_head wb_queue; /* Queue of processes wanting to do writeback */
- loff_t _remote_i_size; /* Size of the remote file */
- loff_t _zero_point; /* Size after which we assume there's no data
+ uoff_t _remote_i_size; /* Size of the remote file */
+ uoff_t _zero_point; /* Size after which we assume there's no data
* on the server */
spinlock_t lock; /* Lock covering wb_queue */
atomic_t io_count; /* Number of outstanding reqs */
@@ -142,7 +142,7 @@ struct netfs_io_stream {
void (*issue_write)(struct netfs_io_subrequest *subreq);
/* Collection tracking */
struct list_head subrequests; /* Contributory I/O operations */
- unsigned long long collected_to; /* Position we've collected results to */
+ uoff_t collected_to; /* Position we've collected results to */
size_t transferred; /* The amount transferred from this stream */
unsigned short error; /* Aggregate error for the stream */
enum netfs_io_source source; /* Where to read from/write to */
@@ -161,7 +161,8 @@ struct netfs_cache_resources {
const struct netfs_cache_ops *ops;
void *cache_priv;
void *cache_priv2;
- unsigned int debug_id; /* Cookie debug ID */
+ unsigned int cookie_id; /* Cache cookie debug ID */
+ unsigned int object_id; /* Cache object debug ID */
unsigned int inval_counter; /* object->inval_counter at begin_op */
};
@@ -177,7 +178,7 @@ struct netfs_io_subrequest {
struct work_struct work;
struct list_head rreq_link; /* Link in rreq->subrequests */
struct iov_iter io_iter; /* Iterator for this subrequest */
- unsigned long long start; /* Where to start the I/O */
+ uoff_t start; /* Where to start the I/O */
size_t len; /* Size of the I/O */
size_t transferred; /* Amount of data transferred */
refcount_t ref;
@@ -208,7 +209,6 @@ enum netfs_io_origin {
NETFS_DIO_READ, /* This is a direct I/O read */
NETFS_WRITEBACK, /* This write was triggered by writepages */
NETFS_WRITEBACK_SINGLE, /* This monolithic write was triggered by writepages */
- NETFS_WRITETHROUGH, /* This write was made by netfs_perform_write() */
NETFS_UNBUFFERED_WRITE, /* This is an unbuffered write */
NETFS_DIO_WRITE, /* This is a direct I/O write */
NETFS_PGPRIV2_COPY_TO_CACHE, /* [DEPRECATED] This is writing read data to the cache */
@@ -243,17 +243,17 @@ struct netfs_io_request {
void *netfs_priv; /* Private data for the netfs */
void *netfs_priv2; /* Private data for the netfs */
struct bio_vec *direct_bv; /* DIO buffer list (when handling iovec-iter) */
- unsigned long long submitted; /* Amount submitted for I/O so far */
- unsigned long long len; /* Length of the request */
+ uoff_t submitted; /* Amount submitted for I/O so far */
+ uoff_t len; /* Length of the request */
size_t transferred; /* Amount to be indicated as transferred */
size_t progress_at; /* Report read progress when hit this much read */
long error; /* 0 or error that occurred */
- unsigned long long i_size; /* Size of the file */
- unsigned long long start; /* Start position */
+ uoff_t i_size; /* Size of the file */
+ uoff_t start; /* Start position */
atomic64_t issued_to; /* Write issuer folio cursor */
- unsigned long long collected_to; /* Point we've collected to */
- unsigned long long cleaned_to; /* Position we've cleaned folios to */
- unsigned long long abandon_to; /* Position to abandon folios to */
+ uoff_t collected_to; /* Point we've collected to */
+ uoff_t cleaned_to; /* Position we've cleaned folios to */
+ uoff_t abandon_to; /* Position to abandon folios to */
const struct folio *no_unlock_folio; /* Don't unlock this folio after read */
gfp_t gfp; /* GFP flags to use */
unsigned int direct_bv_count; /* Number of elements in direct_bv[] */
@@ -279,8 +279,10 @@ struct netfs_io_request {
#define NETFS_RREQ_UPLOAD_TO_SERVER 11 /* Need to write to the server */
#define NETFS_RREQ_USE_IO_ITER 12 /* Use ->io_iter rather than ->i_pages */
#define NETFS_RREQ_NEED_PUT_RA_REFS 17 /* Need to put the folio refs RA gave us */
+#ifdef CONFIG_NETFS_PGPRIV2
#define NETFS_RREQ_USE_PGPRIV2 31 /* [DEPRECATED] Use PG_private_2 to mark
* write to cache on read */
+#endif
const struct netfs_request_ops *netfs_ops;
};
@@ -299,12 +301,12 @@ struct netfs_request_ops {
int (*prepare_read)(struct netfs_io_subrequest *subreq);
void (*issue_read)(struct netfs_io_subrequest *subreq);
bool (*is_still_valid)(struct netfs_io_request *rreq);
- int (*check_write_begin)(struct file *file, loff_t pos, unsigned len,
+ int (*check_write_begin)(struct file *file, uoff_t pos, unsigned len,
struct folio **foliop, void **_fsdata);
void (*done)(struct netfs_io_request *rreq);
/* Modification handling */
- void (*update_i_size)(struct inode *inode, loff_t i_size);
+ void (*update_i_size)(struct inode *inode, uoff_t i_size);
void (*post_modify)(struct inode *inode);
/* Write request handling */
@@ -332,7 +334,7 @@ struct netfs_cache_ops {
/* Read data from the cache */
int (*read)(struct netfs_cache_resources *cres,
- loff_t start_pos,
+ uoff_t start_pos,
struct iov_iter *iter,
enum netfs_read_from_hole read_hole,
netfs_io_terminated_t term_func,
@@ -340,7 +342,7 @@ struct netfs_cache_ops {
/* Write data to the cache */
int (*write)(struct netfs_cache_resources *cres,
- loff_t start_pos,
+ uoff_t start_pos,
struct iov_iter *iter,
netfs_io_terminated_t term_func,
void *term_func_priv);
@@ -350,15 +352,15 @@ struct netfs_cache_ops {
/* Expand readahead request */
void (*expand_readahead)(struct netfs_cache_resources *cres,
- unsigned long long *_start,
- unsigned long long *_len,
- unsigned long long i_size);
+ uoff_t *_start,
+ uoff_t *_len,
+ uoff_t i_size);
/* Prepare a read operation, shortening it to a cached/uncached
* boundary as appropriate.
*/
enum netfs_io_source (*prepare_read)(struct netfs_io_subrequest *subreq,
- unsigned long long i_size);
+ uoff_t i_size);
/* Prepare a write subrequest, working out if we're allowed to do it
* and finding out the maximum amount of data to gather before
@@ -371,15 +373,15 @@ struct netfs_cache_ops {
* actually do.
*/
int (*prepare_write)(struct netfs_cache_resources *cres,
- loff_t *_start, size_t *_len, size_t upper_len,
- loff_t i_size, bool no_space_allocated_yet);
+ uoff_t *_start, size_t *_len, size_t upper_len,
+ uoff_t i_size, bool no_space_allocated_yet);
/* Query the occupancy of the cache in a region, returning where the
* next chunk of data starts and how long it is.
*/
int (*query_occupancy)(struct netfs_cache_resources *cres,
- loff_t start, size_t len, size_t granularity,
- loff_t *_data_start, size_t *_data_len);
+ uoff_t start, size_t len, size_t granularity,
+ uoff_t *_data_start, size_t *_data_len);
};
/* High-level read API. */
@@ -410,7 +412,7 @@ struct readahead_control;
void netfs_readahead(struct readahead_control *);
int netfs_read_folio(struct file *, struct folio *);
int netfs_write_begin(struct netfs_inode *, struct file *,
- struct address_space *, loff_t pos, unsigned int len,
+ struct address_space *, uoff_t pos, unsigned int len,
struct folio **, void **fsdata);
int netfs_writepages(struct address_space *mapping,
struct writeback_control *wbc);
@@ -488,10 +490,10 @@ static inline struct netfs_inode *netfs_inode(struct inode *inode)
* cmpxchg8b without the need of the lock prefix). For SMP compiles and 64bit
* archs it makes no difference if preempt is enabled or not.
*/
-static inline unsigned long long netfs_read_remote_i_size(const struct inode *inode)
+static inline uoff_t netfs_read_remote_i_size(const struct inode *inode)
{
const struct netfs_inode *ictx = container_of(inode, struct netfs_inode, inode);
- unsigned long long remote_i_size;
+ uoff_t remote_i_size;
#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
unsigned int seq;
@@ -526,7 +528,7 @@ static inline unsigned long long netfs_read_remote_i_size(const struct inode *in
* spinning forever.
*/
static inline void netfs_write_remote_i_size(struct inode *inode,
- unsigned long long remote_i_size)
+ uoff_t remote_i_size)
{
struct netfs_inode *ictx = netfs_inode(inode);
@@ -563,10 +565,10 @@ static inline void netfs_write_remote_i_size(struct inode *inode,
* cmpxchg8b without the need of the lock prefix). For SMP compiles and 64bit
* archs it makes no difference if preempt is enabled or not.
*/
-static inline unsigned long long netfs_read_zero_point(const struct inode *inode)
+static inline uoff_t netfs_read_zero_point(const struct inode *inode)
{
struct netfs_inode *ictx = container_of(inode, struct netfs_inode, inode);
- unsigned long long zero_point;
+ uoff_t zero_point;
#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
unsigned int seq;
@@ -601,7 +603,7 @@ static inline unsigned long long netfs_read_zero_point(const struct inode *inode
* forever.
*/
static inline void netfs_write_zero_point(struct inode *inode,
- unsigned long long zero_point)
+ uoff_t zero_point)
{
struct netfs_inode *ictx = netfs_inode(inode);
@@ -642,9 +644,9 @@ static inline void netfs_write_zero_point(struct inode *inode,
* archs it makes no difference if preempt is enabled or not.
*/
static inline void netfs_read_sizes(const struct inode *inode,
- unsigned long long *i_size,
- unsigned long long *remote_i_size,
- unsigned long long *zero_point)
+ uoff_t *i_size,
+ uoff_t *remote_i_size,
+ uoff_t *zero_point)
{
const struct netfs_inode *ictx = container_of(inode, struct netfs_inode, inode);
#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
@@ -690,9 +692,9 @@ static inline void netfs_read_sizes(const struct inode *inode,
* forever.
*/
static inline void netfs_write_sizes(struct inode *inode,
- unsigned long long i_size,
- unsigned long long remote_i_size,
- unsigned long long zero_point)
+ uoff_t i_size,
+ uoff_t remote_i_size,
+ uoff_t zero_point)
{
struct netfs_inode *ictx = netfs_inode(inode);
@@ -760,7 +762,7 @@ static inline void netfs_inode_init(struct netfs_inode *ctx,
* Inform the netfs lib that a file got resized so that it can adjust its state.
*/
static inline void netfs_resize_file(struct netfs_inode *ictx,
- unsigned long long new_i_size,
+ uoff_t new_i_size,
bool changed_on_server)
{
#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
diff --git a/include/trace/events/cachefiles.h b/include/trace/events/cachefiles.h
index e3101410e8b2d..1938d51a94594 100644
--- a/include/trace/events/cachefiles.h
+++ b/include/trace/events/cachefiles.h
@@ -449,7 +449,7 @@ TRACE_EVENT(cachefiles_vol_coherency,
TRACE_EVENT(cachefiles_prep_read,
TP_PROTO(struct cachefiles_object *obj,
- loff_t start,
+ uoff_t start,
size_t len,
unsigned short flags,
enum netfs_io_source source,
@@ -464,7 +464,7 @@ TRACE_EVENT(cachefiles_prep_read,
__field(enum netfs_io_source, source)
__field(enum cachefiles_prepare_read_trace, why)
__field(size_t, len)
- __field(loff_t, start)
+ __field(uoff_t, start)
__field(unsigned int, netfs_inode)
__field(unsigned int, cache_inode)
),
@@ -492,16 +492,16 @@ TRACE_EVENT(cachefiles_prep_read,
TRACE_EVENT(cachefiles_read,
TP_PROTO(struct cachefiles_object *obj,
struct inode *backer,
- loff_t start,
+ uoff_t start,
size_t len),
TP_ARGS(obj, backer, start, len),
TP_STRUCT__entry(
- __field(unsigned int, obj)
- __field(unsigned int, backer)
- __field(size_t, len)
- __field(loff_t, start)
+ __field(unsigned int, obj)
+ __field(unsigned int, backer)
+ __field(size_t, len)
+ __field(uoff_t, start)
),
TP_fast_assign(
@@ -521,16 +521,16 @@ TRACE_EVENT(cachefiles_read,
TRACE_EVENT(cachefiles_write,
TP_PROTO(struct cachefiles_object *obj,
struct inode *backer,
- loff_t start,
+ uoff_t start,
size_t len),
TP_ARGS(obj, backer, start, len),
TP_STRUCT__entry(
- __field(unsigned int, obj)
- __field(unsigned int, backer)
- __field(size_t, len)
- __field(loff_t, start)
+ __field(unsigned int, obj)
+ __field(unsigned int, backer)
+ __field(size_t, len)
+ __field(uoff_t, start)
),
TP_fast_assign(
@@ -549,7 +549,7 @@ TRACE_EVENT(cachefiles_write,
TRACE_EVENT(cachefiles_trunc,
TP_PROTO(struct cachefiles_object *obj, struct inode *backer,
- loff_t from, loff_t to, enum cachefiles_trunc_trace why),
+ uoff_t from, uoff_t to, enum cachefiles_trunc_trace why),
TP_ARGS(obj, backer, from, to, why),
@@ -557,8 +557,8 @@ TRACE_EVENT(cachefiles_trunc,
__field(unsigned int, obj)
__field(unsigned int, backer)
__field(enum cachefiles_trunc_trace, why)
- __field(loff_t, from)
- __field(loff_t, to)
+ __field(uoff_t, from)
+ __field(uoff_t, to)
),
TP_fast_assign(
diff --git a/include/trace/events/fscache.h b/include/trace/events/fscache.h
index f1a73aa83fbbf..8735d428ebd9b 100644
--- a/include/trace/events/fscache.h
+++ b/include/trace/events/fscache.h
@@ -460,13 +460,13 @@ TRACE_EVENT(fscache_relinquish,
);
TRACE_EVENT(fscache_invalidate,
- TP_PROTO(struct fscache_cookie *cookie, loff_t new_size),
+ TP_PROTO(struct fscache_cookie *cookie, uoff_t new_size),
TP_ARGS(cookie, new_size),
TP_STRUCT__entry(
__field(unsigned int, cookie )
- __field(loff_t, new_size )
+ __field(uoff_t, new_size )
),
TP_fast_assign(
@@ -479,14 +479,14 @@ TRACE_EVENT(fscache_invalidate,
);
TRACE_EVENT(fscache_resize,
- TP_PROTO(struct fscache_cookie *cookie, loff_t new_size),
+ TP_PROTO(struct fscache_cookie *cookie, uoff_t new_size),
TP_ARGS(cookie, new_size),
TP_STRUCT__entry(
__field(unsigned int, cookie )
- __field(loff_t, old_size )
- __field(loff_t, new_size )
+ __field(uoff_t, old_size )
+ __field(uoff_t, new_size )
),
TP_fast_assign(
diff --git a/include/trace/events/netfs.h b/include/trace/events/netfs.h
index 3fec3e8f91c85..303309be253f2 100644
--- a/include/trace/events/netfs.h
+++ b/include/trace/events/netfs.h
@@ -30,8 +30,7 @@
EM(netfs_write_trace_dio_write, "DIO-WRITE") \
EM(netfs_write_trace_unbuffered_write, "UNB-WRITE") \
EM(netfs_write_trace_writeback, "WRITEBACK") \
- EM(netfs_write_trace_writeback_single, "WB-SINGLE") \
- E_(netfs_write_trace_writethrough, "WRITETHRU")
+ E_(netfs_write_trace_writeback_single, "WB-SINGLE")
#define netfs_rreq_origins \
EM(NETFS_READAHEAD, "RA") \
@@ -43,12 +42,12 @@
EM(NETFS_DIO_READ, "DR") \
EM(NETFS_WRITEBACK, "WB") \
EM(NETFS_WRITEBACK_SINGLE, "W1") \
- EM(NETFS_WRITETHROUGH, "WT") \
EM(NETFS_UNBUFFERED_WRITE, "UW") \
EM(NETFS_DIO_WRITE, "DW") \
E_(NETFS_PGPRIV2_COPY_TO_CACHE, "2C")
#define netfs_rreq_traces \
+ EM(netfs_rreq_trace_all_queued, "ALL-Q ") \
EM(netfs_rreq_trace_assess, "ASSESS ") \
EM(netfs_rreq_trace_collect, "COLLECT") \
EM(netfs_rreq_trace_complete, "COMPLET") \
@@ -194,11 +193,11 @@
EM(netfs_folio_trace_alloc_buffer, "alloc-buf") \
EM(netfs_folio_trace_cancel_copy, "cancel-copy") \
EM(netfs_folio_trace_cancel_store, "cancel-store") \
- EM(netfs_folio_trace_clear, "clear") \
- EM(netfs_folio_trace_clear_cc, "clear-cc") \
- EM(netfs_folio_trace_clear_g, "clear-g") \
- EM(netfs_folio_trace_clear_s, "clear-s") \
EM(netfs_folio_trace_end_copy, "end-copy") \
+ EM(netfs_folio_trace_endwb, "endwb") \
+ EM(netfs_folio_trace_endwb_cc, "endwb-cc") \
+ EM(netfs_folio_trace_endwb_g, "endwb-g") \
+ EM(netfs_folio_trace_endwb_s, "endwb-s") \
EM(netfs_folio_trace_filled_gaps, "filled-gaps") \
EM(netfs_folio_trace_invalidate_all, "inval-all") \
EM(netfs_folio_trace_invalidate_front, "inval-front") \
@@ -223,9 +222,7 @@
EM(netfs_folio_trace_sched_copy, "sched-copy") \
EM(netfs_folio_trace_store, "store") \
EM(netfs_folio_trace_store_copy, "store-copy") \
- EM(netfs_folio_trace_store_plus, "store+") \
- EM(netfs_folio_trace_wthru, "wthru") \
- E_(netfs_folio_trace_wthru_plus, "wthru+")
+ E_(netfs_folio_trace_store_plus, "store+")
#define netfs_collect_contig_traces \
EM(netfs_contig_trace_collect, "Collect") \
@@ -301,7 +298,7 @@ netfs_folioq_traces;
TRACE_EVENT(netfs_read,
TP_PROTO(struct netfs_io_request *rreq,
- loff_t start, size_t len,
+ uoff_t start, size_t len,
enum netfs_read_trace what),
TP_ARGS(rreq, start, len, what),
@@ -309,8 +306,9 @@ TRACE_EVENT(netfs_read,
TP_STRUCT__entry(
__field(unsigned int, rreq)
__field(unsigned int, cookie)
- __field(loff_t, i_size)
- __field(loff_t, start)
+ __field(unsigned int, object)
+ __field(uoff_t, i_size)
+ __field(uoff_t, start)
__field(size_t, len)
__field(enum netfs_read_trace, what)
__field(u64, netfs_inode)
@@ -318,7 +316,8 @@ TRACE_EVENT(netfs_read,
TP_fast_assign(
__entry->rreq = rreq->debug_id;
- __entry->cookie = rreq->cache_resources.debug_id;
+ __entry->cookie = rreq->cache_resources.cookie_id;
+ __entry->object = rreq->cache_resources.object_id;
__entry->i_size = rreq->i_size;
__entry->start = start;
__entry->len = len;
@@ -326,10 +325,10 @@ TRACE_EVENT(netfs_read,
__entry->netfs_inode = rreq->inode->i_ino;
),
- TP_printk("R=%08x %s c=%08x ni=%llx s=%llx l=%zx sz=%llx",
+ TP_printk("R=%08x %s c=%08x o=%08x ni=%llx s=%llx l=%zx sz=%llx",
__entry->rreq,
__print_symbolic(__entry->what, netfs_read_traces),
- __entry->cookie,
+ __entry->cookie, __entry->object,
__entry->netfs_inode,
__entry->start, __entry->len, __entry->i_size)
);
@@ -377,7 +376,7 @@ TRACE_EVENT(netfs_sreq,
__field(u8, slot)
__field(size_t, len)
__field(size_t, transferred)
- __field(loff_t, start)
+ __field(uoff_t, start)
),
TP_fast_assign(
@@ -418,7 +417,7 @@ TRACE_EVENT(netfs_failure,
__field(enum netfs_failure, what)
__field(size_t, len)
__field(size_t, transferred)
- __field(loff_t, start)
+ __field(uoff_t, start)
),
TP_fast_assign(
@@ -501,6 +500,7 @@ TRACE_EVENT(netfs_folio,
TP_STRUCT__entry(
__field(u64, ino)
__field(pgoff_t, index)
+ __field(unsigned long, pfn)
__field(unsigned int, nr)
__field(enum netfs_folio_trace, why)
),
@@ -511,9 +511,11 @@ TRACE_EVENT(netfs_folio,
__entry->why = why;
__entry->index = folio->index;
__entry->nr = folio_nr_pages(folio);
+ __entry->pfn = folio_pfn(folio);
),
- TP_printk("i=%05llx ix=%05lx-%05lx %s",
+ TP_printk("p=%lx i=%05llx ix=%05lx-%05lx %s",
+ __entry->pfn,
__entry->ino, __entry->index, __entry->index + __entry->nr - 1,
__print_symbolic(__entry->why, netfs_folio_traces))
);
@@ -524,10 +526,10 @@ TRACE_EVENT(netfs_write_iter,
TP_ARGS(iocb, from),
TP_STRUCT__entry(
- __field(unsigned long long, start)
- __field(size_t, len)
- __field(unsigned int, flags)
- __field(unsigned int, ino)
+ __field(uoff_t, start)
+ __field(size_t, len)
+ __field(unsigned int, flags)
+ __field(unsigned int, ino)
),
TP_fast_assign(
@@ -550,27 +552,27 @@ TRACE_EVENT(netfs_write,
TP_STRUCT__entry(
__field(unsigned int, wreq)
__field(unsigned int, cookie)
+ __field(unsigned int, object)
__field(unsigned int, ino)
__field(enum netfs_write_trace, what)
- __field(unsigned long long, start)
- __field(unsigned long long, len)
+ __field(uoff_t, start)
+ __field(uoff_t, len)
),
TP_fast_assign(
- struct netfs_inode *__ctx = netfs_inode(wreq->inode);
- struct fscache_cookie *__cookie = netfs_i_cookie(__ctx);
__entry->wreq = wreq->debug_id;
- __entry->cookie = __cookie ? __cookie->debug_id : 0;
+ __entry->cookie = wreq->cache_resources.cookie_id;
+ __entry->object = wreq->cache_resources.object_id;
__entry->ino = wreq->inode->i_ino;
__entry->what = what;
__entry->start = wreq->start;
__entry->len = wreq->len;
),
- TP_printk("R=%08x %s c=%08x i=%x by=%llx-%llx",
+ TP_printk("R=%08x %s c=%08x o=%08x i=%x by=%llx-%llx",
__entry->wreq,
__print_symbolic(__entry->what, netfs_write_traces),
- __entry->cookie,
+ __entry->cookie, __entry->object,
__entry->ino,
__entry->start, __entry->start + __entry->len - 1)
);
@@ -582,25 +584,26 @@ TRACE_EVENT(netfs_copy2cache,
TP_ARGS(rreq, creq),
TP_STRUCT__entry(
- __field(unsigned int, rreq)
- __field(unsigned int, creq)
- __field(unsigned int, cookie)
- __field(unsigned int, ino)
+ __field(unsigned int, rreq)
+ __field(unsigned int, creq)
+ __field(unsigned int, cookie)
+ __field(unsigned int, object)
+ __field(unsigned int, ino)
),
TP_fast_assign(
- struct netfs_inode *__ctx = netfs_inode(rreq->inode);
- struct fscache_cookie *__cookie = netfs_i_cookie(__ctx);
__entry->rreq = rreq->debug_id;
__entry->creq = creq->debug_id;
- __entry->cookie = __cookie ? __cookie->debug_id : 0;
+ __entry->cookie = rreq->cache_resources.cookie_id;
+ __entry->object = rreq->cache_resources.object_id;
__entry->ino = rreq->inode->i_ino;
),
- TP_printk("R=%08x CR=%08x c=%08x i=%x ",
+ TP_printk("R=%08x CR=%08x c=%08x o=%08x i=%x ",
__entry->rreq,
__entry->creq,
__entry->cookie,
+ __entry->object,
__entry->ino)
);
@@ -610,10 +613,10 @@ TRACE_EVENT(netfs_collect,
TP_ARGS(wreq),
TP_STRUCT__entry(
- __field(unsigned int, wreq)
- __field(unsigned int, len)
- __field(unsigned long long, transferred)
- __field(unsigned long long, start)
+ __field(unsigned int, wreq)
+ __field(unsigned int, len)
+ __field(uoff_t, transferred)
+ __field(uoff_t, start)
),
TP_fast_assign(
@@ -636,12 +639,12 @@ TRACE_EVENT(netfs_collect_sreq,
TP_ARGS(wreq, subreq),
TP_STRUCT__entry(
- __field(unsigned int, wreq)
- __field(unsigned int, subreq)
- __field(unsigned int, stream)
- __field(unsigned int, len)
- __field(unsigned int, transferred)
- __field(unsigned long long, start)
+ __field(unsigned int, wreq)
+ __field(unsigned int, subreq)
+ __field(unsigned int, stream)
+ __field(unsigned int, len)
+ __field(unsigned int, transferred)
+ __field(uoff_t, start)
),
TP_fast_assign(
@@ -660,37 +663,30 @@ TRACE_EVENT(netfs_collect_sreq,
TRACE_EVENT(netfs_collect_folio,
TP_PROTO(const struct netfs_io_request *wreq,
- const struct folio *folio,
- unsigned long long fend,
- unsigned long long collected_to),
+ const struct folio *folio),
- TP_ARGS(wreq, folio, fend, collected_to),
+ TP_ARGS(wreq, folio),
TP_STRUCT__entry(
__field(unsigned int, wreq)
__field(unsigned long, index)
- __field(unsigned long long, fend)
- __field(unsigned long long, cleaned_to)
- __field(unsigned long long, collected_to)
+ __field(unsigned int, nr)
),
TP_fast_assign(
__entry->wreq = wreq->debug_id;
__entry->index = folio->index;
- __entry->fend = fend;
- __entry->cleaned_to = wreq->cleaned_to;
- __entry->collected_to = collected_to;
+ __entry->nr = folio_nr_pages(folio);
),
- TP_printk("R=%08x ix=%05lx r=%llx-%llx t=%llx/%llx",
+ TP_printk("R=%08x ix=%05lx-%05lx",
__entry->wreq, __entry->index,
- (unsigned long long)__entry->index * PAGE_SIZE, __entry->fend,
- __entry->cleaned_to, __entry->collected_to)
+ __entry->index + __entry->nr - 1)
);
TRACE_EVENT(netfs_collect_state,
TP_PROTO(const struct netfs_io_request *wreq,
- unsigned long long collected_to,
+ uoff_t collected_to,
unsigned int notes),
TP_ARGS(wreq, collected_to, notes),
@@ -698,8 +694,8 @@ TRACE_EVENT(netfs_collect_state,
TP_STRUCT__entry(
__field(unsigned int, wreq)
__field(unsigned int, notes)
- __field(unsigned long long, collected_to)
- __field(unsigned long long, cleaned_to)
+ __field(uoff_t, collected_to)
+ __field(uoff_t, cleaned_to)
),
TP_fast_assign(
@@ -718,7 +714,7 @@ TRACE_EVENT(netfs_collect_state,
TRACE_EVENT(netfs_collect_gap,
TP_PROTO(const struct netfs_io_request *wreq,
const struct netfs_io_stream *stream,
- unsigned long long jump_to, char type),
+ uoff_t jump_to, char type),
TP_ARGS(wreq, stream, jump_to, type),
@@ -726,8 +722,8 @@ TRACE_EVENT(netfs_collect_gap,
__field(unsigned int, wreq)
__field(unsigned char, stream)
__field(unsigned char, type)
- __field(unsigned long long, from)
- __field(unsigned long long, to)
+ __field(uoff_t, from)
+ __field(uoff_t, to)
),
TP_fast_assign(
@@ -752,8 +748,8 @@ TRACE_EVENT(netfs_collect_stream,
TP_STRUCT__entry(
__field(unsigned int, wreq)
__field(unsigned char, stream)
- __field(unsigned long long, collected_to)
- __field(unsigned long long, issued_to)
+ __field(uoff_t, collected_to)
+ __field(uoff_t, issued_to)
),
TP_fast_assign(
|
| 3/2 | 2026/09/09 08:19 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 37888 output: 29 thoughts: 983 Thoughts: **Fuzzing Worthiness Evaluation: A Deep Dive** Okay, let's dissect this patch series and determine its fuzzing potential. My initial assessment is looking promising. First, let's get a handle on the scope of the changes. The patch touches a range of files, primarily centered around network filesystems and caching, including `fs/9p/vfs_addr.c`, `fs/afs/file.c`, and a significant overhaul of `fs/netfs`, `fs/cachefiles`, `fs/ceph`, and `fs/nfs`. This is a pretty diverse set of core components. Importantly, it's not just a single, isolated module; we're seeing changes across multiple interacting subsystems. Here are the key aspects that are catching my eye: 1. **Removal and Simplification:** The removal of `NETFS_WRITETHROUGH` and associated functions in `netfs_perform_write` immediately stands out. Anytime we see simplification or removal of logic, it can create opportunities for state transition flaws or errors that were previously masked. 2. **Type Changes:** The introduction of `uoff_t` and the replacement of `loff_t` or `unsigned long long` across several filesystem modules (netfs, fscache, etc.) is a red flag. Type conversions and potential overflow issues are classic fuzzing targets. 3. **New Configuration and Conditional Compilation:** The `CONFIG_NETFS_PGPRIV2` configuration and associated `#ifdef` blocks are intriguing. New code paths often introduce new bugs, and conditional compilation means that certain features are enabled or disabled depending on the build configuration. This potentially expands our coverage surface. 4. **Subrequest Allocation and Helper Functions:** The refactoring of `netfs_alloc_subrequest` and the introduction of helper functions like `netfs_all_subreqs_queued()` and `netfs_are_all_subreqs_queued()` indicate logic in handling concurrent and asynchronous operations. This area is a great place to investigate for concurrency issues. 5. **Tracepoint Updates:** The tracepoint updates in `cachefiles`, `fscache`, and `netfs` might be helpful for observability and diagnostics, and perhaps we can leverage them later in the process. Now, considering reachability, `fs/netfs`, `fs/cachefiles`, `fs/9p`, `fs/afs`, `fs/ceph`, and `fs/nfs` are definitely within core kernel subsystems. They are accessible in a standard QEMU environment, and modifications to `netfs_perform_write()`, `netfs_read_to_pagecache()`, `cachefiles_prepare_write()` and others, suggest these are very likely in critical memory management, VFS, and network filesystem read/write paths. Looking at the positive criteria for determining WorthFuzzing=true from my experience, this patch ticks all the boxes. It modifies core subsystems related to memory management, VFS, and network file systems. We also see refactoring and code cleanup, restructuring key data structures, and algorithm flows. The next step is to nail down the relevant configurations and entry points for a focused fuzzing campaign. Time to bust out the grepper or read the files! |
| 4/2 | 2026/09/09 08:19 | tool | grepper |
0mArgs:{
"Expression": "config NETFS_SUPPORT",
"PathPrefix": "fs/netfs"
}Results: {
"Output": "fs/netfs/Kconfig-2-\nfs/netfs/Kconfig:3:config NETFS_SUPPORT\nfs/netfs/Kconfig-4-\ttristate\n"
} |
| 5/2 | 2026/09/09 08:19 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 39647 output: 33 thoughts: 56 Thoughts: Here's my take on those Kconfig files: **Kconfig Dive: Network Filesystems** Okay, time to get a good handle on the networking filesystem configuration options. I need to make sure I'm across the dependencies and potential conflicts, especially with the direction we're moving in with [mention the relevant project or area you are working on, e.g., the new container filesystem support, the kernel's storage class integration, etc.]. Right, let's start by checking `fs/netfs/Kconfig`. That's the logical starting point. Next, I should check `fs/cachefiles/Kconfig` to see how caching might interact or be a dependency to any of the other filesystems I am checking. Then, `fs/ceph/Kconfig`, that's a crucial one to understand given the shift to distributed storage; want to see how it's being configured. Following that I'll check `fs/nfs/Kconfig`, of course. Gotta refresh my memory on the current NFS implementations and how things are set. After NFS, I need to look into `fs/afs/Kconfig` and `fs/9p/Kconfig`. These are older, but still used in some places and I'm curious if any legacy issues have been addressed or if we can deprecate them safely. Let's see what interesting features and defaults are in these files. This should give me a good lay of the land for these filesystems. |
| 6/2 | 2026/09/09 08:19 | tool | read-file |
0mArgs:{
"File": "fs/netfs/Kconfig",
"FirstLine": 1,
"LineCount": 40
}Results: {
"Contents": " 1:\t# SPDX-License-Identifier: GPL-2.0-only\n 2:\t\n 3:\tconfig NETFS_SUPPORT\n 4:\t\ttristate\n 5:\t\thelp\n 6:\t\t This option enables support for network filesystems, including\n 7:\t\t helpers for high-level buffered I/O, abstracting out read\n 8:\t\t segmentation, local caching and transparent huge page support.\n 9:\t\n 10:\tconfig NETFS_STATS\n 11:\t\tbool \"Gather statistical information on local caching\"\n 12:\t\tdepends on NETFS_SUPPORT \u0026\u0026 PROC_FS\n 13:\t\thelp\n 14:\t\t This option causes statistical information to be gathered on local\n 15:\t\t caching and exported through file:\n 16:\t\n 17:\t\t\t/proc/fs/fscache/stats\n 18:\t\n 19:\t\t The gathering of statistics adds a certain amount of overhead to\n 20:\t\t execution as there are a quite a few stats gathered, and on a\n 21:\t\t multi-CPU system these may be on cachelines that keep bouncing\n 22:\t\t between CPUs. On the other hand, the stats are very useful for\n 23:\t\t debugging purposes. Saying 'Y' here is recommended.\n 24:\t\n 25:\tconfig NETFS_PGPRIV2\n 26:\t\tbool\n 27:\t\n 28:\tconfig NETFS_DEBUG\n 29:\t\tbool \"Enable dynamic debugging netfslib and FS-Cache\"\n 30:\t\tdepends on NETFS_SUPPORT\n 31:\t\thelp\n 32:\t\t This permits debugging to be dynamically enabled in the local caching\n 33:\t\t management module. If this is set, the debugging output may be\n 34:\t\t enabled by setting bits in /sys/module/netfs/parameters/debug.\n 35:\t\n 36:\tconfig FSCACHE\n 37:\t\tbool \"General filesystem local caching manager\"\n 38:\t\tdepends on NETFS_SUPPORT\n 39:\t\thelp\n 40:\t\t This option enables a generic filesystem caching manager that can be\n"
} |
| 7/2 | 2026/09/09 08:19 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 40584 output: 26 thoughts: 13 Thoughts: Here's my attempt at summarizing the thought process, tailored for an expert audience: **Examining the Cachefiles Kconfig** Alright, let's dive in. My immediate thought is, "Okay, `fs/cachefiles/Kconfig` – right, that's where the configuration options for the cachefiles filesystem are defined." I need to understand what's controllable at compile time. What features can be enabled or disabled? Are there any dependencies on other kernel subsystems that I should be aware of, like specific cryptographic algorithms or namespace capabilities? I'm thinking, "I need to look for the core features first." What are the critical booleans that dictate whether the cachefiles code is even *included* in the build? Then, I should scan for any further options that allow a fine-grained tuning of the cache's behavior. I will probably look for any default settings that catch my eye, or potential performance tunables. Maybe some options for debugging that will come in handy. I know the Kconfig syntax well, so I'll be quickly looking for the usual suspects: `bool`, `tristate`, `int`, and `string` types. Dependencies and conditional compilation, and the general structure of the file is what I'm looking for. Let's see what we can find. |
| 8/2 | 2026/09/09 08:20 | tool | grepper |
0mArgs:{
"Expression": "config CACHEFILES",
"PathPrefix": "fs/"
}Results: {
"Output": "fs/cachefiles/Kconfig-2-\nfs/cachefiles/Kconfig:3:config CACHEFILES\nfs/cachefiles/Kconfig-4-\ttristate \"Filesystem caching on files\"\n--\nfs/cachefiles/Kconfig-13-\nfs/cachefiles/Kconfig:14:config CACHEFILES_DEBUG\nfs/cachefiles/Kconfig-15-\tbool \"Debug CacheFiles\"\n--\nfs/cachefiles/Kconfig-22-\nfs/cachefiles/Kconfig:23:config CACHEFILES_ERROR_INJECTION\nfs/cachefiles/Kconfig-24-\tbool \"Provide error injection for cachefiles\"\n"
} |
| 9/2 | 2026/09/09 08:20 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 41064 output: 83 thoughts: 1203 Thoughts: **Analyzing NetFS Configuration and Key Functionality Changes** Okay, let's break this down. First, I need to understand the relationship between the kernel configurations related to network filesystems. From what I see, `NETFS_SUPPORT` is the overarching enabler, used by various netfs implementations like `FSCACHE`, `AFS_FS`, `9P_FS`, `CEPH_FS`, and `NFS_FS`. `FSCACHE` itself, of course, enables fscache support and it seems a new one, `NETFS_PGPRIV2` is introduced and selected by `CEPH_FS` and `NFS_FSCACHE`. Now, the meat of it: the code changes. I'll need to identify the significant function changes in the diff. Looks like the following functions saw major or substantial modifications: 1. `netfs_perform_write` - Big changes here, writethrough has been removed, so I'll want to dig in on memory and control flow. 2. `netfs_alloc_subrequest` - Signature changes and initialisation changes in this helper function require examination. 3. `netfs_read_to_pagecache` - Altered subreq allocation and completion/queuing markers. 4. `netfs_dispatch_unbuffered_reads` - Same as above, altered subreq allocation and queuing markers. 5. `netfs_collect_write_results` - Write results collection modifications. 6. `netfs_write_collection` - Modified write collection logic and subrequest queue checks. 7. `netfs_read_collection` - Similar modifications to read collection logic and subrequest queue checks. 8. `netfs_retry_read_subrequests` and `netfs_retry_write_stream` - subreq allocation and retry logic has been updated. 9. `netfs_prepare_write` and `netfs_write_folio` - Subreq allocation and folio write logic. 10. `cachefiles_prepare_read`, `cachefiles_prepare_write`, `cachefiles_write`, `cachefiles_read` - Cachefiles IO operations. 11. `__fscache_write_to_cache` - FSCache write operation. 12. `netfs_single_dispatch_read` 13. `netfs_folio_written_back` 14. `netfs_writeback_unlock_folios` 15. `netfs_read_unlock_folios` 16. `netfs_pgpriv2_unlock_copied_folios` 17. `netfs_pgpriv2_end_copy_to_cache` Next, I need to know which of these functions are static or exported. That determines how broadly they're used and how changes might ripple through the system. From the code analysis, I can see: * `netfs_perform_write` - Exported, so used by filesystems like 9p and ceph, and important to check for regressions in those filesystems. * `netfs_alloc_subrequest`, `netfs_write_collection`, `netfs_read_collection` are non-static helpers, so will need to be checked in relation to their callsites. * `netfs_writepages` and `netfs_folio_written_back` are non-static, and so broadly used. * `__cachefiles_write` and `__fscache_write_to_cache` are also non-static/exported. * `cachefiles_prepare_read` - Static, so this will only be a relevant area of interest in cachefiles. Finally, I'll need to verify that those specific function names are, in fact, symbols in the kernel. Then, I can focus in more precisely on the most important ones. |
| 10/2 | 2026/09/09 08:20 | tool | grepper |
0mArgs:{
"Expression": "(netfs_perform_write|netfs_alloc_subrequest|netfs_write_collection|netfs_read_collection|netfs_writepages|netfs_folio_written_back|netfs_pgpriv2_unlock_copied_folios)",
"PathPrefix": "fs/netfs/"
}Results: {
"Output": "fs/netfs/buffered_read.c=269=static void netfs_read_to_pagecache(struct netfs_io_request *rreq)\n--\nfs/netfs/buffered_read.c-281-\nfs/netfs/buffered_read.c:282:\t\tsubreq = netfs_alloc_subrequest(rreq, NETFS_SOURCE_UNKNOWN);\nfs/netfs/buffered_read.c-283-\t\tif (!subreq) {\n--\nfs/netfs/buffered_read.c=642=static bool netfs_skip_folio_read(struct folio *folio, uoff_t pos, size_t len,\n--\nfs/netfs/buffered_read.c-705- *\nfs/netfs/buffered_read.c:706: * Note that this should be considered deprecated and netfs_perform_write()\nfs/netfs/buffered_read.c-707- * used instead.\n--\nfs/netfs/buffered_write.c=37=void netfs_update_i_size(struct netfs_inode *ctx, struct inode *inode,\n--\nfs/netfs/buffered_write.c-73-/**\nfs/netfs/buffered_write.c:74: * netfs_perform_write - Copy data into the pagecache.\nfs/netfs/buffered_write.c-75- * @iocb: The operation parameters\n--\nfs/netfs/buffered_write.c-86- */\nfs/netfs/buffered_write.c:87:ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter,\nfs/netfs/buffered_write.c-88-\t\t\t struct netfs_group *netfs_group)\n--\nfs/netfs/buffered_write.c-396-}\nfs/netfs/buffered_write.c:397:EXPORT_SYMBOL(netfs_perform_write);\nfs/netfs/buffered_write.c-398-\n--\nfs/netfs/buffered_write.c=422=ssize_t netfs_buffered_write_iter_locked(struct kiocb *iocb, struct iov_iter *from,\n--\nfs/netfs/buffered_write.c-437-\nfs/netfs/buffered_write.c:438:\treturn netfs_perform_write(iocb, from, netfs_group);\nfs/netfs/buffered_write.c-439-}\n--\nfs/netfs/direct_read.c=48=static void netfs_dispatch_unbuffered_reads(struct netfs_io_request *rreq)\n--\nfs/netfs/direct_read.c-57-\nfs/netfs/direct_read.c:58:\t\tsubreq = netfs_alloc_subrequest(rreq, NETFS_DOWNLOAD_FROM_SERVER);\nfs/netfs/direct_read.c-59-\t\tif (!subreq) {\n--\nfs/netfs/internal.h=94=void netfs_put_failed_request(struct netfs_io_request *rreq);\nfs/netfs/internal.h:95:struct netfs_io_subrequest *netfs_alloc_subrequest(struct netfs_io_request *rreq,\nfs/netfs/internal.h-96-\t\t\t\t\t\t enum netfs_io_source source);\n--\nfs/netfs/internal.h=115=void netfs_read_set_unlock_at(struct netfs_io_request *rreq);\nfs/netfs/internal.h:116:bool netfs_read_collection(struct netfs_io_request *rreq);\nfs/netfs/internal.h:117:void netfs_read_collection_worker(struct work_struct *work);\nfs/netfs/internal.h-118-void netfs_cancel_read(struct netfs_io_subrequest *subreq, int error);\n--\nfs/netfs/internal.h=128=void netfs_pgpriv2_end_copy_to_cache(struct netfs_io_request *rreq);\nfs/netfs/internal.h:129:bool netfs_pgpriv2_unlock_copied_folios(struct netfs_io_request *wreq);\nfs/netfs/internal.h-130-static inline bool netfs_using_pgpriv2(const struct netfs_io_request *rreq)\n--\nfs/netfs/internal.h=143=static inline void netfs_pgpriv2_end_copy_to_cache(struct netfs_io_request *rreq)\n--\nfs/netfs/internal.h-145-}\nfs/netfs/internal.h:146:static inline bool netfs_pgpriv2_unlock_copied_folios(struct netfs_io_request *wreq)\nfs/netfs/internal.h-147-{\n--\nfs/netfs/internal.h=212=static inline void netfs_stat_d(atomic_t *stat)\n--\nfs/netfs/internal.h-224- */\nfs/netfs/internal.h:225:int netfs_folio_written_back(struct folio *folio);\nfs/netfs/internal.h:226:bool netfs_write_collection(struct netfs_io_request *wreq);\nfs/netfs/internal.h:227:void netfs_write_collection_worker(struct work_struct *work);\nfs/netfs/internal.h-228-\n--\nfs/netfs/misc.c=508=ssize_t netfs_wait_for_read(struct netfs_io_request *rreq)\nfs/netfs/misc.c-509-{\nfs/netfs/misc.c:510:\treturn netfs_wait_for_in_progress(rreq, netfs_read_collection);\nfs/netfs/misc.c-511-}\n--\nfs/netfs/misc.c=513=ssize_t netfs_wait_for_write(struct netfs_io_request *rreq)\nfs/netfs/misc.c-514-{\nfs/netfs/misc.c:515:\treturn netfs_wait_for_in_progress(rreq, netfs_write_collection);\nfs/netfs/misc.c-516-}\n--\nfs/netfs/misc.c=557=void netfs_wait_for_paused_read(struct netfs_io_request *rreq)\nfs/netfs/misc.c-558-{\nfs/netfs/misc.c:559:\treturn netfs_wait_for_pause(rreq, netfs_read_collection);\nfs/netfs/misc.c-560-}\n--\nfs/netfs/misc.c=562=void netfs_wait_for_paused_write(struct netfs_io_request *rreq)\nfs/netfs/misc.c-563-{\nfs/netfs/misc.c:564:\treturn netfs_wait_for_pause(rreq, netfs_write_collection);\nfs/netfs/misc.c-565-}\n--\nfs/netfs/objects.c=17=struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,\n--\nfs/netfs/objects.c-76-\t origin == NETFS_DIO_READ) {\nfs/netfs/objects.c:77:\t\tINIT_WORK(\u0026rreq-\u003ework, netfs_read_collection_worker);\nfs/netfs/objects.c-78-\t\trreq-\u003eio_streams[0].avail = true;\nfs/netfs/objects.c-79-\t} else {\nfs/netfs/objects.c:80:\t\tINIT_WORK(\u0026rreq-\u003ework, netfs_write_collection_worker);\nfs/netfs/objects.c-81-\t}\n--\nfs/netfs/objects.c=193=void netfs_put_failed_request(struct netfs_io_request *rreq)\n--\nfs/netfs/objects.c-209- */\nfs/netfs/objects.c:210:struct netfs_io_subrequest *netfs_alloc_subrequest(struct netfs_io_request *rreq,\nfs/netfs/objects.c-211-\t\t\t\t\t\t enum netfs_io_source source)\n--\nfs/netfs/read_collect.c=428=static void netfs_rreq_assess_single(struct netfs_io_request *rreq)\n--\nfs/netfs/read_collect.c-455- */\nfs/netfs/read_collect.c:456:bool netfs_read_collection(struct netfs_io_request *rreq)\nfs/netfs/read_collect.c-457-{\n--\nfs/netfs/read_collect.c-500-\nfs/netfs/read_collect.c:501:void netfs_read_collection_worker(struct work_struct *work)\nfs/netfs/read_collect.c-502-{\n--\nfs/netfs/read_collect.c-506-\tif (netfs_check_rreq_in_progress(rreq)) {\nfs/netfs/read_collect.c:507:\t\tif (netfs_read_collection(rreq))\nfs/netfs/read_collect.c-508-\t\t\t/* Drop the ref from the IN_PROGRESS flag. */\n--\nfs/netfs/read_pgpriv2.c=19=static void netfs_pgpriv2_copy_folio(struct netfs_io_request *creq, struct folio *folio)\n--\nfs/netfs/read_pgpriv2.c-27-\nfs/netfs/read_pgpriv2.c:28:\t/* netfs_perform_write() may shift i_size around the page or from out\nfs/netfs/read_pgpriv2.c-29-\t * of the page to beyond it, but cannot move i_size into or through the\n--\nfs/netfs/read_pgpriv2.c=153=void netfs_pgpriv2_end_copy_to_cache(struct netfs_io_request *rreq)\n--\nfs/netfs/read_pgpriv2.c-173- */\nfs/netfs/read_pgpriv2.c:174:bool netfs_pgpriv2_unlock_copied_folios(struct netfs_io_request *creq)\nfs/netfs/read_pgpriv2.c-175-{\n--\nfs/netfs/read_retry.c=26=static void netfs_retry_read_subrequests(struct netfs_io_request *rreq)\n--\nfs/netfs/read_retry.c-197-\t\tdo {\nfs/netfs/read_retry.c:198:\t\t\tsubreq = netfs_alloc_subrequest(rreq, NETFS_DOWNLOAD_FROM_SERVER);\nfs/netfs/read_retry.c-199-\t\t\tif (!subreq) {\n--\nfs/netfs/read_single.c=90=static int netfs_single_dispatch_read(struct netfs_io_request *rreq)\n--\nfs/netfs/read_single.c-94-\nfs/netfs/read_single.c:95:\tsubreq = netfs_alloc_subrequest(rreq, NETFS_SOURCE_UNKNOWN);\nfs/netfs/read_single.c-96-\tif (!subreq)\n--\nfs/netfs/write_collect.c=24=static void netfs_dump_request(const struct netfs_io_request *rreq)\n--\nfs/netfs/write_collect.c-56- */\nfs/netfs/write_collect.c:57:int netfs_folio_written_back(struct folio *folio)\nfs/netfs/write_collect.c-58-{\n--\nfs/netfs/write_collect.c=114=static void netfs_writeback_unlock_folios(struct netfs_io_request *wreq,\n--\nfs/netfs/write_collect.c-127-\tif (wreq-\u003eorigin == NETFS_PGPRIV2_COPY_TO_CACHE) {\nfs/netfs/write_collect.c:128:\t\tif (netfs_pgpriv2_unlock_copied_folios(wreq))\nfs/netfs/write_collect.c-129-\t\t\t*notes |= MADE_PROGRESS;\n--\nfs/netfs/write_collect.c-164-\nfs/netfs/write_collect.c:165:\t\twreq-\u003enr_group_rel += netfs_folio_written_back(folio);\nfs/netfs/write_collect.c-166-\t\twreq-\u003ecleaned_to = fpos + fsize;\n--\nfs/netfs/write_collect.c=200=static void netfs_collect_write_results(struct netfs_io_request *wreq)\n--\nfs/netfs/write_collect.c-359- */\nfs/netfs/write_collect.c:360:bool netfs_write_collection(struct netfs_io_request *wreq)\nfs/netfs/write_collect.c-361-{\n--\nfs/netfs/write_collect.c-432-\nfs/netfs/write_collect.c:433:void netfs_write_collection_worker(struct work_struct *work)\nfs/netfs/write_collect.c-434-{\n--\nfs/netfs/write_collect.c-438-\tif (netfs_check_rreq_in_progress(rreq)) {\nfs/netfs/write_collect.c:439:\t\tif (netfs_write_collection(rreq))\nfs/netfs/write_collect.c-440-\t\t\t/* Drop the ref from the IN_PROGRESS flag. */\n--\nfs/netfs/write_issue.c=156=void netfs_prepare_write(struct netfs_io_request *wreq,\n--\nfs/netfs/write_issue.c-170-\nfs/netfs/write_issue.c:171:\tsubreq = netfs_alloc_subrequest(wreq, stream-\u003esource);\nfs/netfs/write_issue.c-172-\tif (!subreq)\n--\nfs/netfs/write_issue.c=320=static int netfs_write_folio(struct netfs_io_request *wreq,\n--\nfs/netfs/write_issue.c-339-\nfs/netfs/write_issue.c:340:\t/* netfs_perform_write() may shift i_size around the page or from out\nfs/netfs/write_issue.c-341-\t * of the page to beyond it, but cannot move i_size into or through the\n--\nfs/netfs/write_issue.c-350-\t\tfolio_unlock(folio);\nfs/netfs/write_issue.c:351:\t\twreq-\u003enr_group_rel += netfs_folio_written_back(folio);\nfs/netfs/write_issue.c-352-\t\tnetfs_put_group_many(wreq-\u003egroup, wreq-\u003enr_group_rel);\n--\nfs/netfs/write_issue.c-419-\t\t\tnetfs_issue_write(wreq, upload);\nfs/netfs/write_issue.c:420:\t\t\tnetfs_folio_written_back(folio);\nfs/netfs/write_issue.c-421-\t\t\treturn 0;\n--\nfs/netfs/write_issue.c-425-\t\ttrace_netfs_folio(folio, netfs_folio_trace_cancel_store);\nfs/netfs/write_issue.c:426:\t\tnetfs_folio_written_back(folio);\nfs/netfs/write_issue.c-427-\t\treturn 0;\n--\nfs/netfs/write_issue.c=518=static void netfs_end_issue_write(struct netfs_io_request *wreq)\n--\nfs/netfs/write_issue.c-540- */\nfs/netfs/write_issue.c:541:int netfs_writepages(struct address_space *mapping,\nfs/netfs/write_issue.c-542-\t\t struct writeback_control *wbc)\n--\nfs/netfs/write_issue.c-606-}\nfs/netfs/write_issue.c:607:EXPORT_SYMBOL(netfs_writepages);\nfs/netfs/write_issue.c-608-\n--\nfs/netfs/write_retry.c=17=static void netfs_retry_write_stream(struct netfs_io_request *wreq,\n--\nfs/netfs/write_retry.c-151-\t\tdo {\nfs/netfs/write_retry.c:152:\t\t\tsubreq = netfs_alloc_subrequest(wreq, stream-\u003esource);\nfs/netfs/write_retry.c-153-\t\t\tsubreq-\u003estart\t\t= start;\n"
} |
| 11/2 | 2026/09/09 08:20 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 47474 output: 67 thoughts: 26 Thoughts: Here's my take on the thought process, as if it were my own: **Investigating Potential Cachefile Issues** Okay, so we've got a performance anomaly, and I'm thinking it might be related to the cachefiles subsystem. My first instinct is to dive into the low-level functions involved in writing and managing the cache. I need to refresh my memory on the critical entry points. Let's start by looking specifically at `__cachefiles_write`. That's likely where data is actually being put on the storage. Then I'll check `cachefiles_begin_operation` to see how operations are initiated. I'm also going to cast a wider net and look for other relevant cachefiles symbols; there are a lot of ways to skin this cat, and I want to make sure I'm not missing something fundamental. Essentially, I'm trying to identify the crucial points where we interact with the persistent cache and see if anything jumps out. It is also important to identify all other potentially relevant symbols. |
| 12/2 | 2026/09/09 08:20 | tool | grepper |
0mArgs:{
"Expression": "(__cachefiles_write|cachefiles_prepare_write|cachefiles_prepare_read|cachefiles_begin_operation|cachefiles_shorten_object|cachefiles_resize_cookie)",
"PathPrefix": "fs/cachefiles/"
}Results: {
"Output": "fs/cachefiles/interface.c=172=static bool cachefiles_lookup_cookie(struct fscache_cookie *cookie)\n--\nfs/cachefiles/interface.c-226- */\nfs/cachefiles/interface.c:227:static bool cachefiles_shorten_object(struct cachefiles_object *object,\nfs/cachefiles/interface.c-228-\t\t\t\t struct file *file, uoff_t new_size)\n--\nfs/cachefiles/interface.c-272- */\nfs/cachefiles/interface.c:273:static void cachefiles_resize_cookie(struct netfs_cache_resources *cres,\nfs/cachefiles/interface.c-274-\t\t\t\t uoff_t new_size)\n--\nfs/cachefiles/interface.c-286-\t\tcachefiles_begin_secure(cache, \u0026saved_cred);\nfs/cachefiles/interface.c:287:\t\tcachefiles_shorten_object(object, file, new_size);\nfs/cachefiles/interface.c-288-\t\tcachefiles_end_secure(cache, saved_cred);\n--\nfs/cachefiles/interface.c=443=const struct fscache_cache_ops cachefiles_cache_ops = {\n--\nfs/cachefiles/interface.c-449-\t.invalidate_cookie\t= cachefiles_invalidate_cookie,\nfs/cachefiles/interface.c:450:\t.begin_operation\t= cachefiles_begin_operation,\nfs/cachefiles/interface.c:451:\t.resize_cookie\t\t= cachefiles_resize_cookie,\nfs/cachefiles/interface.c-452-\t.prepare_to_write\t= cachefiles_prepare_to_write,\n--\nfs/cachefiles/internal.h=196=extern void cachefiles_put_object(struct cachefiles_object *object,\n--\nfs/cachefiles/internal.h-201- */\nfs/cachefiles/internal.h:202:extern bool cachefiles_begin_operation(struct netfs_cache_resources *cres,\nfs/cachefiles/internal.h-203-\t\t\t\t enum fscache_want_state want_state);\nfs/cachefiles/internal.h:204:extern int __cachefiles_prepare_write(struct cachefiles_object *object,\nfs/cachefiles/internal.h-205-\t\t\t\t struct file *file,\n--\nfs/cachefiles/internal.h-207-\t\t\t\t bool no_space_allocated_yet);\nfs/cachefiles/internal.h:208:extern int __cachefiles_write(struct cachefiles_object *object,\nfs/cachefiles/internal.h-209-\t\t\t struct file *file,\n--\nfs/cachefiles/io.c=256=static void cachefiles_write_complete(struct kiocb *iocb, long ret)\n--\nfs/cachefiles/io.c-280- */\nfs/cachefiles/io.c:281:int __cachefiles_write(struct cachefiles_object *object,\nfs/cachefiles/io.c-282-\t\t struct file *file,\n--\nfs/cachefiles/io.c=359=static int cachefiles_write(struct netfs_cache_resources *cres,\n--\nfs/cachefiles/io.c-371-\nfs/cachefiles/io.c:372:\treturn __cachefiles_write(cachefiles_cres_object(cres),\nfs/cachefiles/io.c-373-\t\t\t\t cachefiles_cres_file(cres),\n--\nfs/cachefiles/io.c=379=cachefiles_do_prepare_read(struct netfs_cache_resources *cres,\n--\nfs/cachefiles/io.c-382-{\nfs/cachefiles/io.c:383:\tenum cachefiles_prepare_read_trace why;\nfs/cachefiles/io.c-384-\tstruct cachefiles_object *object = NULL;\n--\nfs/cachefiles/io.c-484- */\nfs/cachefiles/io.c:485:static enum netfs_io_source cachefiles_prepare_read(struct netfs_io_subrequest *subreq,\nfs/cachefiles/io.c-486-\t\t\t\t\t\t uoff_t i_size)\n--\nfs/cachefiles/io.c-495- */\nfs/cachefiles/io.c:496:int __cachefiles_prepare_write(struct cachefiles_object *object,\nfs/cachefiles/io.c-497-\t\t\t struct file *file,\n--\nfs/cachefiles/io.c-578-\nfs/cachefiles/io.c:579:static int cachefiles_prepare_write(struct netfs_cache_resources *cres,\nfs/cachefiles/io.c-580-\t\t\t\t uoff_t *_start, size_t *_len, size_t upper_len,\n--\nfs/cachefiles/io.c-595-\tcachefiles_begin_secure(cache, \u0026saved_cred);\nfs/cachefiles/io.c:596:\tret = __cachefiles_prepare_write(object, cachefiles_cres_file(cres),\nfs/cachefiles/io.c-597-\t\t\t\t\t _start, _len, upper_len,\n--\nfs/cachefiles/io.c-602-\nfs/cachefiles/io.c:603:static void cachefiles_prepare_write_subreq(struct netfs_io_subrequest *subreq)\nfs/cachefiles/io.c-604-{\n--\nfs/cachefiles/io.c=622=static void cachefiles_issue_write(struct netfs_io_subrequest *subreq)\n--\nfs/cachefiles/io.c-676-\tcachefiles_begin_secure(cache, \u0026saved_cred);\nfs/cachefiles/io.c:677:\tret = __cachefiles_prepare_write(object, cachefiles_cres_file(cres),\nfs/cachefiles/io.c-678-\t\t\t\t\t \u0026start, \u0026len, len, true);\n--\nfs/cachefiles/io.c=703=static const struct netfs_cache_ops cachefiles_netfs_cache_ops = {\n--\nfs/cachefiles/io.c-707-\t.issue_write\t\t= cachefiles_issue_write,\nfs/cachefiles/io.c:708:\t.prepare_read\t\t= cachefiles_prepare_read,\nfs/cachefiles/io.c:709:\t.prepare_write\t\t= cachefiles_prepare_write,\nfs/cachefiles/io.c:710:\t.prepare_write_subreq\t= cachefiles_prepare_write_subreq,\nfs/cachefiles/io.c-711-\t.query_occupancy\t= cachefiles_query_occupancy,\n--\nfs/cachefiles/io.c-716- */\nfs/cachefiles/io.c:717:bool cachefiles_begin_operation(struct netfs_cache_resources *cres,\nfs/cachefiles/io.c-718-\t\t\t\tenum fscache_want_state want_state)\n"
} |
| 13/2 | 2026/09/09 08:20 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 49573 output: 301 thoughts: 601 Thoughts: **Fuzzing Configuration Rationale** Alright, let's break this down for the fuzzing setup. First, I need to define the critical focus symbols. Based on the refactoring, it's clear we need to target the core I/O functions that are likely to be affected by these changes. I've compiled the following list of `FocusSymbols`: `netfs_perform_write`, `netfs_alloc_subrequest`, `netfs_writepages`, `netfs_write_collection`, `netfs_read_collection`, `netfs_folio_written_back`, `cachefiles_begin_operation`, `__cachefiles_prepare_write`, and `__cachefiles_write`. These are all at the heart of the changes in netfs and fscache, from I/O submission to writeback handling. Next, I need to define the relevant `EnableConfigs`. The patch targets functionality associated with network filesystems. Based on the nature of these changes, the following kernel configurations need to be enabled: `NETFS_SUPPORT`, `FSCACHE`, `CACHEFILES`, `NETFS_PGPRIV2`, `AFS_FS`, `9P_FS`, `CEPH_FS`, and `NFS_FSCACHE`. I have verified that these are actually valid config names, and that they are likely to be related to the core changes within this patch. Looking at the code, it looks like this patch series fundamentally changes the way netfs and fscache handle writes, removing the direct write-through path and simplifying synchronous buffered writes. It seems they're modifying I/O submission, buffering, and writeback logic across various network filesystems, including 9p, Ceph, AFS, and NFS, and cachefiles. This is a clear indicator that fuzzing is necessary to ensure the changes are robust. I've checked to make sure all of the criteria for `set-results` are met: the patch justifies fuzzing with `WorthFuzzing: true`. I have carefully constructed the required lists for `FocusSymbols` and `EnableConfigs`. I'm going to run the `set-results` tool now with this configuration. |
| 14/2 | 2026/09/09 08:20 | tool | set-results |
0mArgs:{
"EnableConfigs": [
"NETFS_SUPPORT",
"FSCACHE",
"CACHEFILES",
"NETFS_PGPRIV2",
"9P_FS",
"AFS_FS",
"CEPH_FS",
"NFS_FSCACHE"
],
"FocusSymbols": [
"netfs_perform_write",
"netfs_alloc_subrequest",
"netfs_writepages",
"netfs_write_collection",
"netfs_read_collection",
"netfs_folio_written_back",
"cachefiles_begin_operation",
"__cachefiles_prepare_write",
"__cachefiles_write"
],
"Reasoning": "The patch series significantly refactors the netfs and fscache subsystems by removing the writethrough write path from netfs_perform_write(), migrating offset/size parameters across netfs and cachefiles to uoff_t, introducing CONFIG_NETFS_PGPRIV2 for modularizing PG_private_2 cache write tracking, refactoring netfs_alloc_subrequest() source initialization, and altering atomic subrequest queue tracking/wake-up logic. These modifications affect core file I/O, buffered write, read collection, and writeback paths in network filesystems (9p, afs, ceph, nfs) and local cachefiles.",
"WorthFuzzing": true
}Results: {
"EnableConfigs": [
"NETFS_SUPPORT",
"FSCACHE",
"CACHEFILES",
"NETFS_PGPRIV2",
"9P_FS",
"AFS_FS",
"CEPH_FS",
"NFS_FSCACHE"
],
"FocusSymbols": [
"netfs_perform_write",
"netfs_alloc_subrequest",
"netfs_writepages",
"netfs_write_collection",
"netfs_read_collection",
"netfs_folio_written_back",
"cachefiles_begin_operation",
"__cachefiles_prepare_write",
"__cachefiles_write"
],
"Reasoning": "The patch series significantly refactors the netfs and fscache subsystems by removing the writethrough write path from netfs_perform_write(), migrating offset/size parameters across netfs and cachefiles to uoff_t, introducing CONFIG_NETFS_PGPRIV2 for modularizing PG_private_2 cache write tracking, refactoring netfs_alloc_subrequest() source initialization, and altering atomic subrequest queue tracking/wake-up logic. These modifications affect core file I/O, buffered write, read collection, and writeback paths in network filesystems (9p, afs, ceph, nfs) and local cachefiles.",
"WorthFuzzing": true
} |
| 15/1 | 2026/09/09 08:20 | action | If |
0mArgs:{
"WorthFuzzing": true
}Results: null |
| 16/2 | 2026/09/09 08:20 | agent | kmsan-evaluator |
0mModel:core Args: null Results: {
"KMSANReasoning": "The patch performs internal refactoring within the netfs and fscache subsystems:\n1. Replaces offset and length types (`loff_t` and `unsigned long long`) with `uoff_t`.\n2. Removes the deprecated `NETFS_WRITETHROUGH` path and related writethrough tracking functions.\n3. Modularizes PG_private_2 read support behind `CONFIG_NETFS_PGPRIV2`.\n4. Refactors `netfs_alloc_subrequest` to pass `enum netfs_io_source` on allocation, where memory is explicitly zeroed via `memset`.\n5. Encapsulates `NETFS_RREQ_ALL_QUEUED` flag operations and updates tracepoints.\n\nNo uninitialized variables or memory buffers are introduced, and no data structures copied to user space or used in conditional logic are left uninitialized. Therefore, standard KASAN/lockdep testing is sufficient and a dedicated KMSAN session is not required.",
"NeedsKMSAN": false
}Instruction: You are an expert Linux kernel security engineer specializing in kernel memory
error detectors (KASAN and KMSAN). Your job is to review the provided patch series and
determine if the code changes justify spawning a dedicated KMSAN (KernelMemorySanitizer)
fuzzing session in addition to standard KASAN fuzzing.
CRITICAL DISTINCTION BETWEEN KASAN AND KMSAN:
- Standard KASAN kernel builds (upstream-apparmor-kasan.config) already enable
a comprehensive suite of debugging tools and sanitizers, including KASAN
(out-of-bounds accesses, use-after-free, double free, invalid free), LOCKDEP
(locking bugs and deadlocks), UB-sanitizers, and memory corruption checks.
- KMSAN (KernelMemorySanitizer) detects reads of UNINITIALIZED memory (stack, heap,
or page allocations) and kernel-to-user memory info-leaks.
Rule: THERE IS NO SENSE IN RUNNING A KMSAN SESSION IF A BUG CAN BE CAUGHT BY KASAN,
LOCKDEP, OR OTHER STANDARD BUG DETECTORS.
A dedicated KMSAN fuzzing session incurs significant resource costs. You must ONLY
set NeedsKMSAN=true if the code changes introduce or expose UNINITIALIZED MEMORY risks
that are detected ONLY by KMSAN.
Look holistically at the patch series and surrounding code. Even if no direct
uninitialized field accesses or new buffer allocations are added in the diff itself,
a patch may alter control flow, bounds checking, or data length calculations in ways
that change how the rest of the code operates on existing buffers (e.g. allowing
uninitialized stack/heap memory to be read, copied to user space, or used in control
flow). Do not hesitate to use your code access tools to inspect the surrounding code,
called functions, and callers.
Set NeedsKMSAN=true ONLY IF the patch introduces or modifies:
1. Kernel structures sent to user space (via copy_to_user, put_user, netlink skb
attributes, ioctl output arguments, socket options, or BPF buffers) where fields
or structure padding might not be fully initialized/zeroed.
2. Conditional logic or branching that depends on potentially uninitialized variables
or struct fields.
3. Allocation or initialization of complex data structures where uninitialized fields
could be read later in reachable code paths.
4. Bounds checks, lengths, or logic in a way that allows surrounding code to access
uninitialized bytes of existing buffers.
Set NeedsKMSAN=false IF:
- The code changes primarily risk out-of-bounds access, array overflows, NULL pointer
dereferences, locking deadlocks, or use-after-free bugs (these are already caught
by KASAN, LOCKDEP, or standard bug detectors).
- All stack/heap structures touched or introduced by the patch are fully zeroed
or initialized (e.g. using = {0}, memset, kzalloc) before being read or copied.
- The patch does not introduce any risk of uninitialized memory usage or info-leaks.
Use your code access tools to inspect the surrounding code if necessary, then provide
detailed KMSANReasoning contrasting KASAN vs KMSAN applicability for this patch.
Prefer calling several tools at the same time to save round-trips.
Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.
Prompt: Target architecture: amd64
For your convenience, here is the diff of the changes:
commit f50aa0a56f8cd08bac1340311f5a577b64be7080
Author: syz-cluster <triage@syzkaller.com>
Date: Wed Sep 9 08:19:43 2026 +0000
syz-cluster: applied patch under review
diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c
index 1ac0b3dcc0778..2129fcb0f65c1 100644
--- a/fs/9p/vfs_addr.c
+++ b/fs/9p/vfs_addr.c
@@ -124,7 +124,6 @@ static int v9fs_init_request(struct netfs_io_request *rreq, struct file *file)
struct p9_fid *fid;
struct dentry *dentry;
bool writing = (rreq->origin == NETFS_READ_FOR_WRITE ||
- rreq->origin == NETFS_WRITETHROUGH ||
rreq->origin == NETFS_UNBUFFERED_WRITE ||
rreq->origin == NETFS_DIO_WRITE);
diff --git a/fs/afs/file.c b/fs/afs/file.c
index 0467742bfeee3..99987f6bbc36a 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -400,7 +400,6 @@ static int afs_init_request(struct netfs_io_request *rreq, struct file *file)
}
break;
case NETFS_WRITEBACK:
- case NETFS_WRITETHROUGH:
case NETFS_UNBUFFERED_WRITE:
case NETFS_DIO_WRITE:
if (S_ISREG(rreq->inode->i_mode))
@@ -413,7 +412,7 @@ static int afs_init_request(struct netfs_io_request *rreq, struct file *file)
return 0;
}
-static int afs_check_write_begin(struct file *file, loff_t pos, unsigned len,
+static int afs_check_write_begin(struct file *file, uoff_t pos, unsigned len,
struct folio **foliop, void **_fsdata)
{
struct afs_vnode *vnode = AFS_FS_I(file_inode(file));
@@ -451,7 +450,7 @@ void afs_set_i_size(struct afs_vnode *vnode, loff_t new_i_size)
fscache_update_cookie(afs_vnode_cache(vnode), NULL, &new_i_size);
}
-static void afs_update_i_size(struct inode *inode, loff_t new_i_size)
+static void afs_update_i_size(struct inode *inode, uoff_t new_i_size)
{
afs_set_i_size(AFS_FS_I(inode), new_i_size);
}
diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c
index 50a000310a8c5..a160d5c3e74c0 100644
--- a/fs/cachefiles/interface.c
+++ b/fs/cachefiles/interface.c
@@ -111,7 +111,7 @@ static int cachefiles_adjust_size(struct cachefiles_object *object)
struct iattr newattrs;
struct file *file = object->file;
uint64_t ni_size;
- loff_t oi_size;
+ uoff_t oi_size;
int ret;
ni_size = object->cookie->object_size;
@@ -225,11 +225,11 @@ static bool cachefiles_lookup_cookie(struct fscache_cookie *cookie)
* any unused granules.
*/
static bool cachefiles_shorten_object(struct cachefiles_object *object,
- struct file *file, loff_t new_size)
+ struct file *file, uoff_t new_size)
{
struct cachefiles_cache *cache = object->volume->cache;
struct inode *inode = file_inode(file);
- loff_t i_size, dio_size;
+ uoff_t i_size, dio_size;
int ret;
dio_size = round_up(new_size, CACHEFILES_DIO_BLOCK_SIZE);
@@ -271,14 +271,14 @@ static bool cachefiles_shorten_object(struct cachefiles_object *object,
* Resize the backing object.
*/
static void cachefiles_resize_cookie(struct netfs_cache_resources *cres,
- loff_t new_size)
+ uoff_t new_size)
{
struct cachefiles_object *object = cachefiles_cres_object(cres);
struct cachefiles_cache *cache = object->volume->cache;
struct fscache_cookie *cookie = object->cookie;
const struct cred *saved_cred;
struct file *file = cachefiles_cres_file(cres);
- loff_t old_size = cookie->object_size;
+ uoff_t old_size = cookie->object_size;
_enter("%llu->%llu", old_size, new_size);
diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h
index c93324e0f98c7..60bd801ada04f 100644
--- a/fs/cachefiles/internal.h
+++ b/fs/cachefiles/internal.h
@@ -203,11 +203,11 @@ extern bool cachefiles_begin_operation(struct netfs_cache_resources *cres,
enum fscache_want_state want_state);
extern int __cachefiles_prepare_write(struct cachefiles_object *object,
struct file *file,
- loff_t *_start, size_t *_len, size_t upper_len,
+ uoff_t *_start, size_t *_len, size_t upper_len,
bool no_space_allocated_yet);
extern int __cachefiles_write(struct cachefiles_object *object,
struct file *file,
- loff_t start_pos,
+ uoff_t start_pos,
struct iov_iter *iter,
netfs_io_terminated_t term_func,
void *term_func_priv);
diff --git a/fs/cachefiles/io.c b/fs/cachefiles/io.c
index 9540ec25b3cb6..e61e885784d69 100644
--- a/fs/cachefiles/io.c
+++ b/fs/cachefiles/io.c
@@ -19,7 +19,7 @@
struct cachefiles_kiocb {
struct kiocb iocb;
refcount_t ki_refcnt;
- loff_t start;
+ uoff_t start;
union {
size_t skipped;
size_t len;
@@ -73,7 +73,7 @@ static void cachefiles_read_complete(struct kiocb *iocb, long ret)
* Initiate a read from the cache.
*/
static int cachefiles_read(struct netfs_cache_resources *cres,
- loff_t start_pos,
+ uoff_t start_pos,
struct iov_iter *iter,
enum netfs_read_from_hole read_hole,
netfs_io_terminated_t term_func,
@@ -197,8 +197,8 @@ static int cachefiles_read(struct netfs_cache_resources *cres,
* of data starts and how long it is.
*/
static int cachefiles_query_occupancy(struct netfs_cache_resources *cres,
- loff_t start, size_t len, size_t granularity,
- loff_t *_data_start, size_t *_data_len)
+ uoff_t start, size_t len, size_t granularity,
+ uoff_t *_data_start, size_t *_data_len)
{
struct cachefiles_object *object;
struct file *file;
@@ -280,7 +280,7 @@ static void cachefiles_write_complete(struct kiocb *iocb, long ret)
*/
int __cachefiles_write(struct cachefiles_object *object,
struct file *file,
- loff_t start_pos,
+ uoff_t start_pos,
struct iov_iter *iter,
netfs_io_terminated_t term_func,
void *term_func_priv)
@@ -357,7 +357,7 @@ int __cachefiles_write(struct cachefiles_object *object,
}
static int cachefiles_write(struct netfs_cache_resources *cres,
- loff_t start_pos,
+ uoff_t start_pos,
struct iov_iter *iter,
netfs_io_terminated_t term_func,
void *term_func_priv)
@@ -377,7 +377,7 @@ static int cachefiles_write(struct netfs_cache_resources *cres,
static inline enum netfs_io_source
cachefiles_do_prepare_read(struct netfs_cache_resources *cres,
- loff_t start, size_t *_len, loff_t i_size,
+ uoff_t start, size_t *_len, loff_t i_size,
unsigned long *_flags, ino_t netfs_ino)
{
enum cachefiles_prepare_read_trace why;
@@ -483,7 +483,7 @@ cachefiles_do_prepare_read(struct netfs_cache_resources *cres,
* boundary as appropriate.
*/
static enum netfs_io_source cachefiles_prepare_read(struct netfs_io_subrequest *subreq,
- unsigned long long i_size)
+ uoff_t i_size)
{
return cachefiles_do_prepare_read(&subreq->rreq->cache_resources,
subreq->start, &subreq->len, i_size,
@@ -495,7 +495,7 @@ static enum netfs_io_source cachefiles_prepare_read(struct netfs_io_subrequest *
*/
int __cachefiles_prepare_write(struct cachefiles_object *object,
struct file *file,
- loff_t *_start, size_t *_len, size_t upper_len,
+ uoff_t *_start, size_t *_len, size_t upper_len,
bool no_space_allocated_yet)
{
struct cachefiles_cache *cache = object->volume->cache;
@@ -577,8 +577,8 @@ int __cachefiles_prepare_write(struct cachefiles_object *object,
}
static int cachefiles_prepare_write(struct netfs_cache_resources *cres,
- loff_t *_start, size_t *_len, size_t upper_len,
- loff_t i_size, bool no_space_allocated_yet)
+ uoff_t *_start, size_t *_len, size_t upper_len,
+ uoff_t i_size, bool no_space_allocated_yet)
{
struct cachefiles_object *object = cachefiles_cres_object(cres);
struct cachefiles_cache *cache = object->volume->cache;
@@ -628,7 +628,7 @@ static void cachefiles_issue_write(struct netfs_io_subrequest *subreq)
struct netfs_io_stream *stream = &wreq->io_streams[subreq->stream_nr];
const struct cred *saved_cred;
size_t off, pre, post, len = subreq->len;
- loff_t start = subreq->start;
+ uoff_t start = subreq->start;
int ret;
_enter("W=%x[%x] %llx-%llx",
@@ -721,6 +721,7 @@ bool cachefiles_begin_operation(struct netfs_cache_resources *cres,
if (!cachefiles_cres_file(cres)) {
cres->ops = &cachefiles_netfs_cache_ops;
+ cres->object_id = object->debug_id;
if (object->file) {
spin_lock(&object->lock);
if (!cres->cache_priv2 && object->file)
diff --git a/fs/ceph/Kconfig b/fs/ceph/Kconfig
index 3d64a316ca31d..aa6ccd7794d23 100644
--- a/fs/ceph/Kconfig
+++ b/fs/ceph/Kconfig
@@ -4,6 +4,7 @@ config CEPH_FS
depends on INET
select CEPH_LIB
select NETFS_SUPPORT
+ select NETFS_PGPRIV2
select FS_ENCRYPTION_ALGS if FS_ENCRYPTION
default n
help
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index ecf33b66610c8..6586f6c1dc734 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -65,7 +65,7 @@
(CONGESTION_ON_THRESH(congestion_kb) - \
(CONGESTION_ON_THRESH(congestion_kb) >> 2))
-static int ceph_netfs_check_write_begin(struct file *file, loff_t pos, unsigned int len,
+static int ceph_netfs_check_write_begin(struct file *file, uoff_t pos, unsigned int len,
struct folio **foliop, void **_fsdata);
static inline struct ceph_snap_context *page_snap_context(struct page *page)
@@ -1854,7 +1854,7 @@ ceph_find_incompatible(struct folio *folio)
return NULL;
}
-static int ceph_netfs_check_write_begin(struct file *file, loff_t pos, unsigned int len,
+static int ceph_netfs_check_write_begin(struct file *file, uoff_t pos, unsigned int len,
struct folio **foliop, void **_fsdata)
{
struct inode *inode = file_inode(file);
diff --git a/fs/netfs/Kconfig b/fs/netfs/Kconfig
index 7701c037c3283..d0e7b0971fa3f 100644
--- a/fs/netfs/Kconfig
+++ b/fs/netfs/Kconfig
@@ -22,6 +22,9 @@ config NETFS_STATS
between CPUs. On the other hand, the stats are very useful for
debugging purposes. Saying 'Y' here is recommended.
+config NETFS_PGPRIV2
+ bool
+
config NETFS_DEBUG
bool "Enable dynamic debugging netfslib and FS-Cache"
depends on NETFS_SUPPORT
diff --git a/fs/netfs/Makefile b/fs/netfs/Makefile
index b43188d64bd87..54834cde7e568 100644
--- a/fs/netfs/Makefile
+++ b/fs/netfs/Makefile
@@ -11,7 +11,6 @@ netfs-y := \
misc.o \
objects.o \
read_collect.o \
- read_pgpriv2.o \
read_retry.o \
read_single.o \
rolling_buffer.o \
@@ -19,6 +18,7 @@ netfs-y := \
write_issue.o \
write_retry.o
+netfs-$(CONFIG_NETFS_PGPRIV2) += read_pgpriv2.o
netfs-$(CONFIG_NETFS_STATS) += stats.o
netfs-$(CONFIG_FSCACHE) += \
diff --git a/fs/netfs/buffered_read.c b/fs/netfs/buffered_read.c
index 424df70a5c30f..68496e1a171f5 100644
--- a/fs/netfs/buffered_read.c
+++ b/fs/netfs/buffered_read.c
@@ -10,9 +10,9 @@
#include "internal.h"
static void netfs_cache_expand_readahead(struct netfs_io_request *rreq,
- unsigned long long *_start,
- unsigned long long *_len,
- unsigned long long i_size)
+ uoff_t *_start,
+ uoff_t *_len,
+ uoff_t i_size)
{
struct netfs_cache_resources *cres = &rreq->cache_resources;
@@ -139,7 +139,7 @@ static ssize_t netfs_prepare_read_iterator(struct netfs_io_subrequest *subreq)
static enum netfs_io_source netfs_cache_prepare_read(struct netfs_io_request *rreq,
struct netfs_io_subrequest *subreq,
- loff_t i_size)
+ uoff_t i_size)
{
struct netfs_cache_resources *cres = &rreq->cache_resources;
enum netfs_io_source source;
@@ -242,7 +242,7 @@ static void netfs_mark_copy_to_cache(struct netfs_io_request *rreq,
if (overlap > 0 && copy) {
folio = folioq_folio(*fq, *slot);
- if (unlikely(test_bit(NETFS_RREQ_USE_PGPRIV2, &rreq->flags))) {
+ if (netfs_using_pgpriv2(rreq)) {
if (!folio_test_private_2(folio))
folio_start_private_2(folio);
} else {
@@ -269,17 +269,17 @@ static void netfs_mark_copy_to_cache(struct netfs_io_request *rreq,
static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
{
struct folio_queue *fq = rreq->buffer.tail;
- unsigned long long start = rreq->start;
unsigned int offset = 0;
ssize_t size = rreq->len;
+ uoff_t start = rreq->start;
int ret = 0, slot = 0;
do {
struct netfs_io_subrequest *subreq;
- enum netfs_io_source source = NETFS_SOURCE_UNKNOWN;
+ enum netfs_io_source source;
ssize_t slice;
- subreq = netfs_alloc_subrequest(rreq);
+ subreq = netfs_alloc_subrequest(rreq, NETFS_SOURCE_UNKNOWN);
if (!subreq) {
ret = -ENOMEM;
break;
@@ -293,8 +293,8 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
source = netfs_cache_prepare_read(rreq, subreq, rreq->i_size);
subreq->source = source;
if (source == NETFS_DOWNLOAD_FROM_SERVER) {
- unsigned long long zero_point = netfs_read_zero_point(rreq->inode);
- unsigned long long zp = umin(zero_point, rreq->i_size);
+ uoff_t zero_point = netfs_read_zero_point(rreq->inode);
+ uoff_t zp = umin(zero_point, rreq->i_size);
size_t len = subreq->len;
if (unlikely(rreq->origin == NETFS_READ_SINGLE))
@@ -355,10 +355,8 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
}
start += slice;
size -= slice;
- if (size <= 0) {
- smp_wmb(); /* Write lists before ALL_QUEUED. */
- set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
- }
+ if (size <= 0)
+ netfs_all_subreqs_queued(rreq);
if (fq) {
/* See if the cache indicated this should be cached. */
@@ -378,8 +376,7 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
} while (size > 0);
if (unlikely(size > 0)) {
- smp_wmb(); /* Write lists before ALL_QUEUED. */
- set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
+ netfs_all_subreqs_queued(rreq);
netfs_wake_collector(rreq);
}
@@ -642,11 +639,11 @@ EXPORT_SYMBOL(netfs_read_folio);
* If any of these criteria are met, then zero out the unwritten parts
* of the folio and return true. Otherwise, return false.
*/
-static bool netfs_skip_folio_read(struct folio *folio, loff_t pos, size_t len,
+static bool netfs_skip_folio_read(struct folio *folio, uoff_t pos, size_t len,
bool always_fill)
{
struct inode *inode = folio_inode(folio);
- loff_t i_size = i_size_read(inode);
+ uoff_t i_size = i_size_read(inode);
size_t offset = offset_in_folio(folio, pos);
size_t plen = folio_size(folio);
@@ -711,7 +708,7 @@ static bool netfs_skip_folio_read(struct folio *folio, loff_t pos, size_t len,
*/
int netfs_write_begin(struct netfs_inode *ctx,
struct file *file, struct address_space *mapping,
- loff_t pos, unsigned int len, struct folio **_folio,
+ uoff_t pos, unsigned int len, struct folio **_folio,
void **_fsdata)
{
struct netfs_io_request *rreq;
@@ -807,7 +804,7 @@ int netfs_prefetch_for_write(struct file *file, struct folio *folio,
struct netfs_io_request *rreq;
struct address_space *mapping = folio->mapping;
struct netfs_inode *ctx = netfs_inode(mapping->host);
- unsigned long long start = folio_pos(folio);
+ uoff_t start = folio_pos(folio);
size_t flen = folio_size(folio);
int ret;
diff --git a/fs/netfs/buffered_write.c b/fs/netfs/buffered_write.c
index 2cdb68e6b16ff..ead22980075fe 100644
--- a/fs/netfs/buffered_write.c
+++ b/fs/netfs/buffered_write.c
@@ -17,7 +17,7 @@
* as possible to hold as much of the remaining length as possible in one go.
*/
static struct folio *netfs_grab_folio_for_write(struct address_space *mapping,
- loff_t pos, size_t part)
+ uoff_t pos, size_t part)
{
pgoff_t index = pos / PAGE_SIZE;
fgf_t fgp_flags = FGP_WRITEBEGIN;
@@ -35,9 +35,9 @@ static struct folio *netfs_grab_folio_for_write(struct address_space *mapping,
* the values actually are.
*/
void netfs_update_i_size(struct netfs_inode *ctx, struct inode *inode,
- loff_t pos, size_t copied)
+ uoff_t pos, size_t copied)
{
- loff_t i_size, end = pos + copied;
+ uoff_t i_size, end = pos + copied;
blkcnt_t add;
size_t gap;
@@ -91,50 +91,20 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter,
struct inode *inode = file_inode(file);
struct address_space *mapping = inode->i_mapping;
struct netfs_inode *ctx = netfs_inode(inode);
- struct writeback_control wbc = {
- .sync_mode = WB_SYNC_NONE,
- .for_sync = true,
- .nr_to_write = LONG_MAX,
- .range_start = iocb->ki_pos,
- .range_end = iocb->ki_pos + iter->count,
- };
- struct netfs_io_request *wreq = NULL;
- struct folio *folio = NULL, *writethrough = NULL;
+ struct folio *folio = NULL;
unsigned int bdp_flags = (iocb->ki_flags & IOCB_NOWAIT) ? BDP_ASYNC : 0;
- ssize_t written = 0, ret, ret2;
- loff_t pos = iocb->ki_pos;
+ ssize_t written = 0, ret;
+ uoff_t pos = iocb->ki_pos;
size_t max_chunk = mapping_max_folio_size(mapping);
bool maybe_trouble = false;
- if (unlikely(iocb->ki_flags & (IOCB_DSYNC | IOCB_SYNC))
- ) {
- wbc_attach_fdatawrite_inode(&wbc, mapping->host);
-
- ret = filemap_write_and_wait_range(mapping, pos, pos + iter->count);
- if (ret < 0) {
- wbc_detach_inode(&wbc);
- goto out;
- }
-
- wreq = netfs_begin_writethrough(iocb, iter->count);
- if (IS_ERR(wreq)) {
- wbc_detach_inode(&wbc);
- ret = PTR_ERR(wreq);
- wreq = NULL;
- goto out;
- }
- if (!is_sync_kiocb(iocb))
- wreq->iocb = iocb;
- netfs_stat(&netfs_n_wh_writethrough);
- } else {
- netfs_stat(&netfs_n_wh_buffered_write);
- }
+ netfs_stat(&netfs_n_wh_buffered_write);
do {
enum netfs_folio_trace trace;
struct netfs_folio *finfo;
struct netfs_group *group;
- unsigned long long fpos;
+ uoff_t fpos;
size_t flen;
size_t offset; /* Offset into pagecache folio */
size_t part; /* Bytes to write to folio */
@@ -390,15 +360,8 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter,
pos += copied;
written += copied;
- if (likely(!wreq)) {
- folio_mark_dirty(folio);
- folio_unlock(folio);
- } else {
- netfs_advance_writethrough(wreq, &wbc, folio, copied,
- offset + copied == flen,
- &writethrough);
- /* Folio unlocked */
- }
+ folio_mark_dirty(folio);
+ folio_unlock(folio);
retry:
folio_put(folio);
folio = NULL;
@@ -420,15 +383,6 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter,
ctx->ops->post_modify(inode);
}
- if (unlikely(wreq)) {
- ret2 = netfs_end_writethrough(wreq, &wbc, writethrough);
- wbc_detach_inode(&wbc);
- if (ret2 == -EIOCBQUEUED)
- return ret2;
- if (ret == 0 && ret2 < 0)
- ret = ret2;
- }
-
iocb->ki_pos += written;
_leave(" = %zd [%zd]", written, ret);
return written ? written : ret;
diff --git a/fs/netfs/direct_read.c b/fs/netfs/direct_read.c
index 6a8fb0d55e040..8c15f30797238 100644
--- a/fs/netfs/direct_read.c
+++ b/fs/netfs/direct_read.c
@@ -47,15 +47,15 @@ static void netfs_prepare_dio_read_iterator(struct netfs_io_subrequest *subreq)
*/
static void netfs_dispatch_unbuffered_reads(struct netfs_io_request *rreq)
{
- unsigned long long start = rreq->start;
ssize_t size = rreq->len;
+ uoff_t start = rreq->start;
int ret;
do {
struct netfs_io_subrequest *subreq;
ssize_t slice;
- subreq = netfs_alloc_subrequest(rreq);
+ subreq = netfs_alloc_subrequest(rreq, NETFS_DOWNLOAD_FROM_SERVER);
if (!subreq) {
/* Stash the error in the request if there's not
* already an error set.
@@ -64,7 +64,6 @@ static void netfs_dispatch_unbuffered_reads(struct netfs_io_request *rreq)
break;
}
- subreq->source = NETFS_DOWNLOAD_FROM_SERVER;
subreq->start = start;
subreq->len = size;
@@ -84,10 +83,8 @@ static void netfs_dispatch_unbuffered_reads(struct netfs_io_request *rreq)
size -= slice;
start += slice;
rreq->submitted += slice;
- if (size <= 0) {
- smp_wmb(); /* Write lists before ALL_QUEUED. */
- set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
- }
+ if (size <= 0)
+ netfs_all_subreqs_queued(rreq);
rreq->netfs_ops->issue_read(subreq);
@@ -99,8 +96,7 @@ static void netfs_dispatch_unbuffered_reads(struct netfs_io_request *rreq)
} while (size > 0);
if (unlikely(size > 0)) {
- smp_wmb(); /* Write lists before ALL_QUEUED. */
- set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
+ netfs_all_subreqs_queued(rreq);
netfs_wake_collector(rreq);
}
}
diff --git a/fs/netfs/direct_write.c b/fs/netfs/direct_write.c
index 2361277416c73..32200c10d2a45 100644
--- a/fs/netfs/direct_write.c
+++ b/fs/netfs/direct_write.c
@@ -225,9 +225,9 @@ ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov_iter *
struct netfs_group *netfs_group)
{
struct netfs_io_request *wreq;
- unsigned long long start = iocb->ki_pos;
- unsigned long long end = start + iov_iter_count(iter);
ssize_t ret, n;
+ uoff_t start = iocb->ki_pos;
+ uoff_t end = start + iov_iter_count(iter);
size_t len = iov_iter_count(iter);
bool async = !is_sync_kiocb(iocb);
@@ -336,8 +336,8 @@ ssize_t netfs_unbuffered_write_iter(struct kiocb *iocb, struct iov_iter *from)
struct inode *inode = mapping->host;
struct netfs_inode *ictx = netfs_inode(inode);
ssize_t ret;
- loff_t pos = iocb->ki_pos;
- unsigned long long end = pos + iov_iter_count(from) - 1;
+ uoff_t pos = iocb->ki_pos;
+ uoff_t end = pos + iov_iter_count(from) - 1;
_enter("%llx,%zx,%llx", pos, iov_iter_count(from), i_size_read(inode));
diff --git a/fs/netfs/fscache_cookie.c b/fs/netfs/fscache_cookie.c
index 3d56fc73435ff..5a226f9cbdeaa 100644
--- a/fs/netfs/fscache_cookie.c
+++ b/fs/netfs/fscache_cookie.c
@@ -327,7 +327,7 @@ static struct fscache_cookie *fscache_alloc_cookie(
u8 advice,
const void *index_key, size_t index_key_len,
const void *aux_data, size_t aux_data_len,
- loff_t object_size)
+ uoff_t object_size)
{
struct fscache_cookie *cookie;
@@ -452,7 +452,7 @@ struct fscache_cookie *__fscache_acquire_cookie(
u8 advice,
const void *index_key, size_t index_key_len,
const void *aux_data, size_t aux_data_len,
- loff_t object_size)
+ uoff_t object_size)
{
struct fscache_cookie *cookie;
@@ -663,7 +663,7 @@ static void fscache_unuse_cookie_locked(struct fscache_cookie *cookie)
* Stop using the cookie for I/O.
*/
void __fscache_unuse_cookie(struct fscache_cookie *cookie,
- const void *aux_data, const loff_t *object_size)
+ const void *aux_data, const uoff_t *object_size)
{
unsigned int debug_id = cookie->debug_id;
unsigned int r = refcount_read(&cookie->ref);
@@ -1049,7 +1049,7 @@ static void fscache_perform_invalidation(struct fscache_cookie *cookie)
* Invalidate an object.
*/
void __fscache_invalidate(struct fscache_cookie *cookie,
- const void *aux_data, loff_t new_size,
+ const void *aux_data, uoff_t new_size,
unsigned int flags)
{
bool is_caching;
diff --git a/fs/netfs/fscache_io.c b/fs/netfs/fscache_io.c
index 37f05b4d34699..056a2bae5d99a 100644
--- a/fs/netfs/fscache_io.c
+++ b/fs/netfs/fscache_io.c
@@ -79,7 +79,7 @@ static int fscache_begin_operation(struct netfs_cache_resources *cres,
cres->ops = NULL;
cres->cache_priv = cookie;
cres->cache_priv2 = NULL;
- cres->debug_id = cookie->debug_id;
+ cres->cookie_id = cookie->debug_id;
cres->inval_counter = cookie->inval_counter;
if (!fscache_begin_cookie_access(cookie, why)) {
@@ -162,7 +162,7 @@ EXPORT_SYMBOL(__fscache_begin_write_operation);
struct fscache_write_request {
struct netfs_cache_resources cache_resources;
struct address_space *mapping;
- loff_t start;
+ uoff_t start;
size_t len;
bool set_bits;
bool using_pgpriv2;
@@ -171,7 +171,7 @@ struct fscache_write_request {
};
void __fscache_clear_page_bits(struct address_space *mapping,
- loff_t start, size_t len)
+ uoff_t start, size_t len)
{
pgoff_t first = start / PAGE_SIZE;
pgoff_t last = (start + len - 1) / PAGE_SIZE;
@@ -208,7 +208,7 @@ static void fscache_wreq_done(void *priv, ssize_t transferred_or_error)
void __fscache_write_to_cache(struct fscache_cookie *cookie,
struct address_space *mapping,
- loff_t start, size_t len, loff_t i_size,
+ uoff_t start, size_t len, uoff_t i_size,
netfs_io_terminated_t term_func,
void *term_func_priv,
bool using_pgpriv2, bool cond)
@@ -267,7 +267,7 @@ EXPORT_SYMBOL(__fscache_write_to_cache);
/*
* Change the size of a backing object.
*/
-void __fscache_resize_cookie(struct fscache_cookie *cookie, loff_t new_size)
+void __fscache_resize_cookie(struct fscache_cookie *cookie, uoff_t new_size)
{
struct netfs_cache_resources cres;
diff --git a/fs/netfs/internal.h b/fs/netfs/internal.h
index c79c8e69d60ca..4891e6e3c5db6 100644
--- a/fs/netfs/internal.h
+++ b/fs/netfs/internal.h
@@ -33,7 +33,7 @@ int netfs_prefetch_for_write(struct file *file, struct folio *folio,
* buffered_write.c
*/
void netfs_update_i_size(struct netfs_inode *ctx, struct inode *inode,
- loff_t pos, size_t copied);
+ uoff_t pos, size_t copied);
/*
* main.c
@@ -86,13 +86,14 @@ void netfs_wait_for_put_ra_refs(struct netfs_io_request *rreq);
*/
struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,
struct file *file,
- loff_t start, size_t len,
+ uoff_t start, size_t len,
enum netfs_io_origin origin);
void netfs_get_request(struct netfs_io_request *rreq, enum netfs_rreq_ref_trace what);
void netfs_clear_subrequests(struct netfs_io_request *rreq);
void netfs_put_request(struct netfs_io_request *rreq, enum netfs_rreq_ref_trace what);
void netfs_put_failed_request(struct netfs_io_request *rreq);
-struct netfs_io_subrequest *netfs_alloc_subrequest(struct netfs_io_request *rreq);
+struct netfs_io_subrequest *netfs_alloc_subrequest(struct netfs_io_request *rreq,
+ enum netfs_io_source source);
static inline void netfs_see_request(struct netfs_io_request *rreq,
enum netfs_rreq_ref_trace what)
@@ -120,9 +121,37 @@ void netfs_cache_read_terminated(void *priv, ssize_t transferred_or_error);
/*
* read_pgpriv2.c
*/
+#ifdef CONFIG_NETFS_PGPRIV2
+int netfs_prepare_pgpriv2_write_buffer(struct netfs_io_subrequest *subreq,
+ unsigned int max_segs);
void netfs_pgpriv2_copy_to_cache(struct netfs_io_request *rreq, struct folio *folio);
void netfs_pgpriv2_end_copy_to_cache(struct netfs_io_request *rreq);
bool netfs_pgpriv2_unlock_copied_folios(struct netfs_io_request *wreq);
+static inline bool netfs_using_pgpriv2(const struct netfs_io_request *rreq)
+{
+ return unlikely(test_bit(NETFS_RREQ_USE_PGPRIV2, &rreq->flags));
+}
+#else
+static inline int netfs_prepare_pgpriv2_write_buffer(struct netfs_io_subrequest *subreq,
+ unsigned int max_segs)
+{
+ return -EIO;
+}
+static inline void netfs_pgpriv2_copy_to_cache(struct netfs_io_request *rreq, struct folio *folio)
+{
+}
+static inline void netfs_pgpriv2_end_copy_to_cache(struct netfs_io_request *rreq)
+{
+}
+static inline bool netfs_pgpriv2_unlock_copied_folios(struct netfs_io_request *wreq)
+{
+ return true;
+}
+static inline bool netfs_using_pgpriv2(const struct netfs_io_request *rreq)
+{
+ return false;
+}
+#endif
/*
* read_retry.c
@@ -157,7 +186,6 @@ extern atomic_t netfs_n_rh_write_zskip;
extern atomic_t netfs_n_rh_retry_read_req;
extern atomic_t netfs_n_rh_retry_read_subreq;
extern atomic_t netfs_n_wh_buffered_write;
-extern atomic_t netfs_n_wh_writethrough;
extern atomic_t netfs_n_wh_dio_write;
extern atomic_t netfs_n_wh_writepages;
extern atomic_t netfs_n_wh_copy_to_cache;
@@ -203,11 +231,11 @@ void netfs_write_collection_worker(struct work_struct *work);
*/
struct netfs_io_request *netfs_create_write_req(struct address_space *mapping,
struct file *file,
- loff_t start,
+ uoff_t start,
enum netfs_io_origin origin);
void netfs_prepare_write(struct netfs_io_request *wreq,
struct netfs_io_stream *stream,
- loff_t start);
+ uoff_t start);
void netfs_reissue_write(struct netfs_io_stream *stream,
struct netfs_io_subrequest *subreq,
struct iov_iter *source);
@@ -215,13 +243,7 @@ void netfs_issue_write(struct netfs_io_request *wreq,
struct netfs_io_stream *stream);
size_t netfs_advance_write(struct netfs_io_request *wreq,
struct netfs_io_stream *stream,
- loff_t start, size_t len, bool to_eof);
-struct netfs_io_request *netfs_begin_writethrough(struct kiocb *iocb, size_t len);
-int netfs_advance_writethrough(struct netfs_io_request *wreq, struct writeback_control *wbc,
- struct folio *folio, size_t copied, bool to_page_end,
- struct folio **writethrough_cache);
-ssize_t netfs_end_writethrough(struct netfs_io_request *wreq, struct writeback_control *wbc,
- struct folio *writethrough_cache);
+ uoff_t start, size_t len, bool to_eof);
/*
* write_retry.c
@@ -320,6 +342,26 @@ static inline bool netfs_check_subreq_in_progress(const struct netfs_io_subreque
return test_bit_acquire(NETFS_SREQ_IN_PROGRESS, &subreq->flags);
}
+/*
+ * Indicate that we've generated and queued all the subrequests we're going to.
+ */
+static inline void netfs_all_subreqs_queued(struct netfs_io_request *rreq)
+{
+ smp_wmb(); /* Write lists before ALL_QUEUED. */
+ set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
+ smp_mb__after_atomic();
+ trace_netfs_rreq(rreq, netfs_rreq_trace_all_queued);
+}
+
+/*
+ * Query if all subrequests are queued.
+ */
+static inline bool netfs_are_all_subreqs_queued(const struct netfs_io_request *rreq)
+{
+ /* Read lists after ALL_QUEUED. */
+ return test_bit_acquire(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
+}
+
/*
* fscache-cache.c
*/
diff --git a/fs/netfs/iterator.c b/fs/netfs/iterator.c
index b375567e0520e..eb1efb17f53aa 100644
--- a/fs/netfs/iterator.c
+++ b/fs/netfs/iterator.c
@@ -209,7 +209,7 @@ static size_t netfs_limit_xarray(const struct iov_iter *iter, size_t start_offse
{
struct folio *folio;
unsigned int nsegs = 0;
- loff_t pos = iter->xarray_start + iter->iov_offset;
+ uoff_t pos = iter->xarray_start + iter->iov_offset;
pgoff_t index = pos / PAGE_SIZE;
size_t span = 0, n = iter->count;
diff --git a/fs/netfs/main.c b/fs/netfs/main.c
index 927badf3989db..609e22e8f76a0 100644
--- a/fs/netfs/main.c
+++ b/fs/netfs/main.c
@@ -44,7 +44,6 @@ static const char *netfs_origins[nr__netfs_io_origin] = {
[NETFS_DIO_READ] = "DR",
[NETFS_WRITEBACK] = "WB",
[NETFS_WRITEBACK_SINGLE] = "W1",
- [NETFS_WRITETHROUGH] = "WT",
[NETFS_UNBUFFERED_WRITE] = "UW",
[NETFS_DIO_WRITE] = "DW",
[NETFS_PGPRIV2_COPY_TO_CACHE] = "2C",
diff --git a/fs/netfs/misc.c b/fs/netfs/misc.c
index f5c1c463f4ff7..a3cd76d584b8b 100644
--- a/fs/netfs/misc.c
+++ b/fs/netfs/misc.c
@@ -193,7 +193,7 @@ void netfs_clear_inode_writeback(struct inode *inode, const void *aux)
struct fscache_cookie *cookie = netfs_i_cookie(netfs_inode(inode));
if (inode_state_read_once(inode) & I_PINNING_NETFS_WB) {
- loff_t i_size = i_size_read(inode);
+ uoff_t i_size = i_size_read(inode);
fscache_unuse_cookie(cookie, aux, &i_size);
}
}
@@ -218,8 +218,8 @@ void netfs_invalidate_folio(struct folio *folio, size_t offset, size_t length)
_enter("{%lx},%zx,%zx", folio->index, offset, length);
if (offset == 0 && length == flen) {
- unsigned long long i_size, remote_i_size, zero_point;
- unsigned long long fpos = folio_pos(folio), end;
+ uoff_t i_size, remote_i_size, zero_point;
+ uoff_t fpos = folio_pos(folio), end;
netfs_read_sizes(inode, &i_size, &remote_i_size, &zero_point);
end = umin(fpos + flen, i_size);
@@ -305,7 +305,7 @@ bool netfs_release_folio(struct folio *folio, gfp_t gfp)
{
struct inode *inode = folio_inode(folio);
struct netfs_inode *ctx = netfs_inode(inode);
- unsigned long long i_size, remote_i_size, zero_point, end;
+ uoff_t i_size, remote_i_size, zero_point, end;
if (folio_test_dirty(folio))
return false;
@@ -424,7 +424,7 @@ static int netfs_collect_in_app(struct netfs_io_request *rreq,
need_collect = true;
break;
}
- if (subreq || !test_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags))
+ if (subreq || !netfs_are_all_subreqs_queued(rreq))
done = false;
}
diff --git a/fs/netfs/objects.c b/fs/netfs/objects.c
index 7f6a3e912602e..9c6ea718692a7 100644
--- a/fs/netfs/objects.c
+++ b/fs/netfs/objects.c
@@ -16,7 +16,7 @@ static void netfs_free_request(struct work_struct *work);
*/
struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,
struct file *file,
- loff_t start, size_t len,
+ uoff_t start, size_t len,
enum netfs_io_origin origin)
{
static atomic_t debug_ids;
@@ -207,7 +207,8 @@ void netfs_put_failed_request(struct netfs_io_request *rreq)
/*
* Allocate and partially initialise an I/O request structure.
*/
-struct netfs_io_subrequest *netfs_alloc_subrequest(struct netfs_io_request *rreq)
+struct netfs_io_subrequest *netfs_alloc_subrequest(struct netfs_io_request *rreq,
+ enum netfs_io_source source)
{
struct netfs_io_subrequest *subreq;
mempool_t *mempool = rreq->netfs_ops->subrequest_pool ?: &netfs_subrequest_pool;
@@ -224,6 +225,7 @@ struct netfs_io_subrequest *netfs_alloc_subrequest(struct netfs_io_request *rreq
INIT_WORK(&subreq->work, NULL);
INIT_LIST_HEAD(&subreq->rreq_link);
refcount_set(&subreq->ref, 2);
+ subreq->source = source;
subreq->rreq = rreq;
subreq->debug_index = atomic_inc_return(&rreq->subreq_counter);
netfs_get_request(rreq, netfs_rreq_trace_get_subreq);
diff --git a/fs/netfs/read_collect.c b/fs/netfs/read_collect.c
index 5cf22087d2439..cb97dedad170f 100644
--- a/fs/netfs/read_collect.c
+++ b/fs/netfs/read_collect.c
@@ -38,7 +38,7 @@ static void netfs_clear_unread(struct netfs_io_subrequest *subreq)
*/
void netfs_cancel_copy_to_cache(struct netfs_io_request *rreq, struct folio *folio)
{
- if (!test_bit(NETFS_RREQ_USE_PGPRIV2, &rreq->flags)) {
+ if (!netfs_using_pgpriv2(rreq)) {
if (folio_get_private(folio) == NETFS_FOLIO_COPY_TO_CACHE) {
folio_detach_private(folio);
trace_netfs_folio(folio, netfs_folio_trace_cancel_copy);
@@ -81,7 +81,7 @@ static void netfs_unlock_read_folio(struct netfs_io_request *rreq,
if (unlikely(test_bit(NETFS_RREQ_CANCEL_CACHING, &rreq->flags)))
netfs_cancel_copy_to_cache(rreq, folio);
- if (!test_bit(NETFS_RREQ_USE_PGPRIV2, &rreq->flags)) {
+ if (!netfs_using_pgpriv2(rreq)) {
if (netfs_folio_group(folio) == NETFS_FOLIO_COPY_TO_CACHE) {
trace_netfs_folio(folio, netfs_folio_trace_sched_copy);
folio_mark_dirty(folio);
@@ -153,8 +153,8 @@ static void netfs_read_unlock_folios(struct netfs_io_request *rreq,
unsigned int *notes)
{
struct folio_queue *folioq = rreq->buffer.tail;
- unsigned long long collected_to = rreq->collected_to;
unsigned int slot = rreq->buffer.first_tail_slot;
+ uoff_t collected_to = rreq->collected_to;
if (rreq->cleaned_to >= rreq->collected_to)
return;
@@ -179,7 +179,7 @@ static void netfs_read_unlock_folios(struct netfs_io_request *rreq,
for (;;) {
struct folio *folio;
- unsigned long long fpos, fend;
+ uoff_t fpos, fend;
size_t fsize;
folio = folioq_folio(folioq, slot);
@@ -192,7 +192,7 @@ static void netfs_read_unlock_folios(struct netfs_io_request *rreq,
fpos = folio_pos(folio);
fend = fpos + fsize;
- trace_netfs_collect_folio(rreq, folio, fend, collected_to);
+ trace_netfs_collect_folio(rreq, folio);
/* Unlock any folio we've transferred all of. */
if (collected_to < fend)
@@ -462,10 +462,8 @@ bool netfs_read_collection(struct netfs_io_request *rreq)
/* We're done when the app thread has finished posting subreqs and the
* queue is empty.
*/
- if (!test_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags))
+ if (!netfs_are_all_subreqs_queued(rreq))
return false;
- smp_rmb(); /* Read ALL_QUEUED before subreq lists. */
-
if (!list_empty(&stream->subrequests))
return false;
diff --git a/fs/netfs/read_pgpriv2.c b/fs/netfs/read_pgpriv2.c
index a4b7bb88cbdb6..5280b606fda41 100644
--- a/fs/netfs/read_pgpriv2.c
+++ b/fs/netfs/read_pgpriv2.c
@@ -20,7 +20,7 @@ static void netfs_pgpriv2_copy_folio(struct netfs_io_request *creq, struct folio
{
struct netfs_io_stream *cache = &creq->io_streams[1];
size_t fsize = folio_size(folio), flen = fsize;
- loff_t fpos = folio_pos(folio), i_size;
+ uoff_t fpos = folio_pos(folio), i_size;
bool to_eof = false;
_enter("");
@@ -158,8 +158,7 @@ void netfs_pgpriv2_end_copy_to_cache(struct netfs_io_request *rreq)
return;
netfs_issue_write(creq, &creq->io_streams[1]);
- smp_wmb(); /* Write lists before ALL_QUEUED. */
- set_bit(NETFS_RREQ_ALL_QUEUED, &creq->flags);
+ netfs_all_subreqs_queued(creq);
trace_netfs_rreq(rreq, netfs_rreq_trace_end_copy_to_cache);
if (list_empty_careful(&creq->io_streams[1].subrequests))
netfs_wake_collector(creq);
@@ -175,8 +174,8 @@ void netfs_pgpriv2_end_copy_to_cache(struct netfs_io_request *rreq)
bool netfs_pgpriv2_unlock_copied_folios(struct netfs_io_request *creq)
{
struct folio_queue *folioq = creq->buffer.tail;
- unsigned long long collected_to = creq->collected_to;
unsigned int slot = creq->buffer.first_tail_slot;
+ uoff_t collected_to = creq->collected_to;
bool made_progress = false;
if (slot >= folioq_nr_slots(folioq)) {
@@ -186,7 +185,7 @@ bool netfs_pgpriv2_unlock_copied_folios(struct netfs_io_request *creq)
for (;;) {
struct folio *folio;
- unsigned long long fpos, fend;
+ uoff_t fpos, fend;
size_t fsize, flen;
folio = folioq_folio(folioq, slot);
@@ -199,9 +198,9 @@ bool netfs_pgpriv2_unlock_copied_folios(struct netfs_io_request *creq)
fsize = folio_size(folio);
flen = fsize;
- fend = min_t(unsigned long long, fpos + flen, creq->i_size);
+ fend = min_t(uoff_t, fpos + flen, creq->i_size);
- trace_netfs_collect_folio(creq, folio, fend, collected_to);
+ trace_netfs_collect_folio(creq, folio);
/* Unlock any folio we've transferred all of. */
if (collected_to < fend)
diff --git a/fs/netfs/read_retry.c b/fs/netfs/read_retry.c
index 4f6a36c6e214f..396a05432a7e9 100644
--- a/fs/netfs/read_retry.c
+++ b/fs/netfs/read_retry.c
@@ -75,7 +75,7 @@ static void netfs_retry_read_subrequests(struct netfs_io_request *rreq)
do {
struct netfs_io_subrequest *from, *to, *tmp;
struct iov_iter source;
- unsigned long long start, len;
+ uoff_t start, len;
size_t part;
bool boundary = false, subreq_superfluous = false;
@@ -195,12 +195,11 @@ static void netfs_retry_read_subrequests(struct netfs_io_request *rreq)
* and insert them after.
*/
do {
- subreq = netfs_alloc_subrequest(rreq);
+ subreq = netfs_alloc_subrequest(rreq, NETFS_DOWNLOAD_FROM_SERVER);
if (!subreq) {
subreq = to;
goto abandon_after;
}
- subreq->source = NETFS_DOWNLOAD_FROM_SERVER;
subreq->start = start;
subreq->len = len;
subreq->stream_nr = stream->stream_nr;
diff --git a/fs/netfs/read_single.c b/fs/netfs/read_single.c
index de67ac41548d1..81295c055cedb 100644
--- a/fs/netfs/read_single.c
+++ b/fs/netfs/read_single.c
@@ -92,11 +92,10 @@ static int netfs_single_dispatch_read(struct netfs_io_request *rreq)
struct netfs_io_subrequest *subreq;
int ret = 0;
- subreq = netfs_alloc_subrequest(rreq);
+ subreq = netfs_alloc_subrequest(rreq, NETFS_SOURCE_UNKNOWN);
if (!subreq)
return -ENOMEM;
- subreq->source = NETFS_SOURCE_UNKNOWN;
subreq->start = 0;
subreq->len = rreq->len;
subreq->io_iter = rreq->buffer.iter;
@@ -113,14 +112,12 @@ static int netfs_single_dispatch_read(struct netfs_io_request *rreq)
goto cancel;
}
- smp_wmb(); /* Write lists before ALL_QUEUED. */
- set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
+ netfs_all_subreqs_queued(rreq);
rreq->netfs_ops->issue_read(subreq);
rreq->submitted += subreq->len;
break;
case NETFS_READ_FROM_CACHE:
- smp_wmb(); /* Write lists before ALL_QUEUED. */
- set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
+ netfs_all_subreqs_queued(rreq);
trace_netfs_sreq(subreq, netfs_sreq_trace_submit);
netfs_single_read_cache(rreq, subreq);
rreq->submitted += subreq->len;
@@ -136,8 +133,7 @@ static int netfs_single_dispatch_read(struct netfs_io_request *rreq)
return ret;
cancel:
netfs_cancel_read(subreq, ret);
- smp_wmb(); /* Write lists before ALL_QUEUED. */
- set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
+ netfs_all_subreqs_queued(rreq);
netfs_wake_collector(rreq);
return ret;
}
diff --git a/fs/netfs/stats.c b/fs/netfs/stats.c
index ab6b916addc44..9a607c4e62dda 100644
--- a/fs/netfs/stats.c
+++ b/fs/netfs/stats.c
@@ -32,7 +32,6 @@ atomic_t netfs_n_rh_write_zskip;
atomic_t netfs_n_rh_retry_read_req;
atomic_t netfs_n_rh_retry_read_subreq;
atomic_t netfs_n_wh_buffered_write;
-atomic_t netfs_n_wh_writethrough;
atomic_t netfs_n_wh_dio_write;
atomic_t netfs_n_wh_writepages;
atomic_t netfs_n_wh_copy_to_cache;
@@ -58,9 +57,8 @@ int netfs_stats_show(struct seq_file *m, void *v)
atomic_read(&netfs_n_rh_read_single),
atomic_read(&netfs_n_rh_write_begin),
atomic_read(&netfs_n_rh_write_zskip));
- seq_printf(m, "Writes : BW=%u WT=%u DW=%u WP=%u 2C=%u\n",
+ seq_printf(m, "Writes : BW=%u DW=%u WP=%u 2C=%u\n",
atomic_read(&netfs_n_wh_buffered_write),
- atomic_read(&netfs_n_wh_writethrough),
atomic_read(&netfs_n_wh_dio_write),
atomic_read(&netfs_n_wh_writepages),
atomic_read(&netfs_n_wh_copy_to_cache));
diff --git a/fs/netfs/write_collect.c b/fs/netfs/write_collect.c
index 210eb8f3958d7..6d99d4a6f7808 100644
--- a/fs/netfs/write_collect.c
+++ b/fs/netfs/write_collect.c
@@ -56,7 +56,7 @@ static void netfs_dump_request(const struct netfs_io_request *rreq)
*/
int netfs_folio_written_back(struct folio *folio)
{
- enum netfs_folio_trace why = netfs_folio_trace_clear;
+ enum netfs_folio_trace why = netfs_folio_trace_endwb;
struct inode *inode = folio_inode(folio);
struct netfs_inode *ictx = netfs_inode(inode);
struct netfs_folio *finfo;
@@ -67,7 +67,7 @@ int netfs_folio_written_back(struct folio *folio)
/* Streaming writes cannot be redirtied whilst under writeback,
* so discard the streaming record.
*/
- unsigned long long fend;
+ uoff_t fend;
fend = folio_pos(folio) + finfo->dirty_offset + finfo->dirty_len;
spin_lock(&ictx->inode.i_lock);
@@ -79,13 +79,13 @@ int netfs_folio_written_back(struct folio *folio)
group = finfo->netfs_group;
gcount++;
kfree(finfo);
- why = netfs_folio_trace_clear_s;
+ why = netfs_folio_trace_endwb_s;
goto end_wb;
}
if ((group = netfs_folio_group(folio))) {
if (group == NETFS_FOLIO_COPY_TO_CACHE) {
- why = netfs_folio_trace_clear_cc;
+ why = netfs_folio_trace_endwb_cc;
folio_detach_private(folio);
goto end_wb;
}
@@ -98,7 +98,7 @@ int netfs_folio_written_back(struct folio *folio)
if (!folio_test_dirty(folio)) {
folio_detach_private(folio);
gcount++;
- why = netfs_folio_trace_clear_g;
+ why = netfs_folio_trace_endwb_g;
}
}
@@ -115,8 +115,8 @@ static void netfs_writeback_unlock_folios(struct netfs_io_request *wreq,
unsigned int *notes)
{
struct folio_queue *folioq = wreq->buffer.tail;
- unsigned long long collected_to = wreq->collected_to;
unsigned int slot = wreq->buffer.first_tail_slot;
+ uoff_t collected_to = wreq->collected_to;
if (WARN_ON_ONCE(!folioq)) {
pr_err("[!] Writeback unlock found empty rolling buffer!\n");
@@ -140,7 +140,7 @@ static void netfs_writeback_unlock_folios(struct netfs_io_request *wreq,
for (;;) {
struct folio *folio;
struct netfs_folio *finfo;
- unsigned long long fpos, fend;
+ uoff_t fpos, fend;
size_t fsize, flen;
folio = folioq_folio(folioq, slot);
@@ -154,9 +154,9 @@ static void netfs_writeback_unlock_folios(struct netfs_io_request *wreq,
finfo = netfs_folio_info(folio);
flen = finfo ? finfo->dirty_offset + finfo->dirty_len : fsize;
- fend = min_t(unsigned long long, fpos + flen, wreq->i_size);
+ fend = min_t(uoff_t, fpos + flen, wreq->i_size);
- trace_netfs_collect_folio(wreq, folio, fend, collected_to);
+ trace_netfs_collect_folio(wreq, folio);
/* Unlock any folio we've transferred all of. */
if (collected_to < fend)
@@ -201,8 +201,8 @@ static void netfs_collect_write_results(struct netfs_io_request *wreq)
{
struct netfs_io_subrequest *front, *remove;
struct netfs_io_stream *stream;
- unsigned long long collected_to, issued_to;
unsigned int notes;
+ uoff_t collected_to, issued_to;
int s;
_enter("%llx-%llx", wreq->start, wreq->start + wreq->len);
@@ -214,7 +214,6 @@ static void netfs_collect_write_results(struct netfs_io_request *wreq)
smp_rmb();
collected_to = ULLONG_MAX;
if (wreq->origin == NETFS_WRITEBACK ||
- wreq->origin == NETFS_WRITETHROUGH ||
wreq->origin == NETFS_PGPRIV2_COPY_TO_CACHE)
notes = NEED_UNLOCK;
else
@@ -372,9 +371,8 @@ bool netfs_write_collection(struct netfs_io_request *wreq)
/* We're done when the app thread has finished posting subreqs and all
* the queues in all the streams are empty.
*/
- if (!test_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags))
+ if (!netfs_are_all_subreqs_queued(wreq))
return false;
- smp_rmb(); /* Read ALL_QUEUED before lists. */
transferred = LONG_MAX;
for (s = 0; s < NR_IO_STREAMS; s++) {
@@ -411,7 +409,6 @@ bool netfs_write_collection(struct netfs_io_request *wreq)
switch (wreq->origin) {
case NETFS_WRITEBACK:
case NETFS_WRITEBACK_SINGLE:
- case NETFS_WRITETHROUGH:
netfs_wb_end(ictx);
break;
default:
diff --git a/fs/netfs/write_issue.c b/fs/netfs/write_issue.c
index 851f6f93ad45a..e7cb496f63246 100644
--- a/fs/netfs/write_issue.c
+++ b/fs/netfs/write_issue.c
@@ -89,14 +89,13 @@ static void netfs_kill_dirty_pages(struct address_space *mapping,
*/
struct netfs_io_request *netfs_create_write_req(struct address_space *mapping,
struct file *file,
- loff_t start,
+ uoff_t start,
enum netfs_io_origin origin)
{
struct netfs_io_request *wreq;
struct netfs_inode *ictx;
bool is_cacheable = (origin == NETFS_WRITEBACK ||
origin == NETFS_WRITEBACK_SINGLE ||
- origin == NETFS_WRITETHROUGH ||
origin == NETFS_PGPRIV2_COPY_TO_CACHE);
wreq = netfs_alloc_request(mapping, file, start, 0, origin);
@@ -156,7 +155,7 @@ EXPORT_SYMBOL(netfs_prepare_write_failed);
*/
void netfs_prepare_write(struct netfs_io_request *wreq,
struct netfs_io_stream *stream,
- loff_t start)
+ uoff_t start)
{
struct netfs_io_subrequest *subreq;
struct iov_iter *wreq_iter = &wreq->buffer.iter;
@@ -169,10 +168,9 @@ void netfs_prepare_write(struct netfs_io_request *wreq,
wreq_iter->folioq_slot >= folioq_nr_slots(wreq_iter->folioq))
rolling_buffer_make_space(&wreq->buffer, wreq->gfp);
- subreq = netfs_alloc_subrequest(wreq);
+ subreq = netfs_alloc_subrequest(wreq, stream->source);
if (!subreq)
return;
- subreq->source = stream->source;
subreq->start = start;
subreq->stream_nr = stream->stream_nr;
subreq->io_iter = *wreq_iter;
@@ -279,7 +277,7 @@ void netfs_issue_write(struct netfs_io_request *wreq,
*/
size_t netfs_advance_write(struct netfs_io_request *wreq,
struct netfs_io_stream *stream,
- loff_t start, size_t len, bool to_eof)
+ uoff_t start, size_t len, bool to_eof)
{
struct netfs_io_subrequest *subreq = stream->construct;
size_t part;
@@ -330,7 +328,7 @@ static int netfs_write_folio(struct netfs_io_request *wreq,
struct netfs_folio *finfo;
size_t iter_off = 0;
size_t fsize = folio_size(folio), flen = fsize, foff = 0;
- loff_t fpos = folio_pos(folio), i_size;
+ uoff_t fpos = folio_pos(folio), i_size;
bool to_eof = false, streamw = false;
bool debug = false;
@@ -367,11 +365,7 @@ static int netfs_write_folio(struct netfs_io_request *wreq,
streamw = true;
}
- if (wreq->origin == NETFS_WRITETHROUGH) {
- to_eof = false;
- if (flen > i_size - fpos)
- flen = i_size - fpos;
- } else if (flen > i_size - fpos) {
+ if (flen > i_size - fpos) {
flen = i_size - fpos;
if (!streamw)
folio_zero_segment(folio, flen, fsize);
@@ -525,8 +519,7 @@ static void netfs_end_issue_write(struct netfs_io_request *wreq)
{
bool needs_poke = true;
- smp_wmb(); /* Write subreq lists before ALL_QUEUED. */
- set_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags);
+ netfs_all_subreqs_queued(wreq);
for (int s = 0; s < NR_IO_STREAMS; s++) {
struct netfs_io_stream *stream = &wreq->io_streams[s];
@@ -613,103 +606,6 @@ int netfs_writepages(struct address_space *mapping,
}
EXPORT_SYMBOL(netfs_writepages);
-/*
- * Begin a write operation for writing through the pagecache.
- */
-struct netfs_io_request *netfs_begin_writethrough(struct kiocb *iocb, size_t len)
-{
- struct netfs_io_request *wreq = NULL;
- struct netfs_inode *ictx = netfs_inode(file_inode(iocb->ki_filp));
-
- netfs_wb_begin(ictx, false);
-
- wreq = netfs_create_write_req(iocb->ki_filp->f_mapping, iocb->ki_filp,
- iocb->ki_pos, NETFS_WRITETHROUGH);
- if (IS_ERR(wreq)) {
- netfs_wb_end(ictx);
- return wreq;
- }
-
- wreq->io_streams[0].avail = true;
- __set_bit(NETFS_RREQ_OFFLOAD_COLLECTION, &wreq->flags);
- trace_netfs_write(wreq, netfs_write_trace_writethrough);
- return wreq;
-}
-
-/*
- * Advance the state of the write operation used when writing through the
- * pagecache. Data has been copied into the pagecache that we need to append
- * to the request. If we've added more than wsize then we need to create a new
- * subrequest.
- */
-int netfs_advance_writethrough(struct netfs_io_request *wreq, struct writeback_control *wbc,
- struct folio *folio, size_t copied, bool to_page_end,
- struct folio **writethrough_cache)
-{
- int ret;
-
- _enter("R=%x ic=%zu ws=%u cp=%zu tp=%u",
- wreq->debug_id, wreq->buffer.iter.count, wreq->wsize, copied, to_page_end);
-
- /* The folio is locked. */
-
- if (*writethrough_cache != folio) {
- if (*writethrough_cache) {
- /* Did the folio get moved? */
- folio_put(*writethrough_cache);
- *writethrough_cache = NULL;
- }
- /* We can make multiple writes to the folio... */
- if (wreq->len == 0)
- trace_netfs_folio(folio, netfs_folio_trace_wthru);
- else
- trace_netfs_folio(folio, netfs_folio_trace_wthru_plus);
- *writethrough_cache = folio;
- folio_get(folio);
- }
-
- wreq->len += copied;
-
- if (!to_page_end) {
- folio_mark_dirty(folio);
- folio_unlock(folio);
- return 0;
- }
-
- ret = netfs_write_folio(wreq, wbc, folio);
- folio_put(*writethrough_cache);
- *writethrough_cache = NULL;
- wreq->submitted = wreq->len;
- return ret;
-}
-
-/*
- * End a write operation used when writing through the pagecache.
- */
-ssize_t netfs_end_writethrough(struct netfs_io_request *wreq, struct writeback_control *wbc,
- struct folio *writethrough_cache)
-{
- ssize_t ret;
-
- _enter("R=%x", wreq->debug_id);
-
- if (writethrough_cache) {
- folio_lock(writethrough_cache);
- netfs_write_folio(wreq, wbc, writethrough_cache);
- folio_put(writethrough_cache);
- wreq->submitted = wreq->len;
- }
-
- netfs_end_issue_write(wreq);
-
- if (wreq->iocb)
- ret = -EIOCBQUEUED;
- else
- ret = netfs_wait_for_write(wreq);
- netfs_put_request(wreq, netfs_rreq_trace_put_return);
- return ret;
-}
-
/*
* Write some of a pending folio data back to the server and/or the cache.
*/
@@ -721,7 +617,7 @@ static int netfs_write_folio_single(struct netfs_io_request *wreq,
struct netfs_io_stream *stream;
size_t iter_off = 0;
size_t fsize = folio_size(folio), flen;
- loff_t fpos = folio_pos(folio);
+ uoff_t fpos = folio_pos(folio);
ssize_t ret;
bool to_eof = false;
bool no_debug = false;
@@ -891,8 +787,7 @@ int netfs_writeback_single(struct address_space *mapping,
stop:
for (int s = 0; s < NR_IO_STREAMS; s++)
netfs_issue_write(wreq, &wreq->io_streams[s]);
- smp_wmb(); /* Write lists before ALL_QUEUED. */
- set_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags);
+ netfs_all_subreqs_queued(wreq);
netfs_wake_collector(wreq);
diff --git a/fs/netfs/write_retry.c b/fs/netfs/write_retry.c
index 058bc7a166a59..d7d5348496fc8 100644
--- a/fs/netfs/write_retry.c
+++ b/fs/netfs/write_retry.c
@@ -55,7 +55,7 @@ static void netfs_retry_write_stream(struct netfs_io_request *wreq,
do {
struct netfs_io_subrequest *subreq = NULL, *from, *to, *tmp;
struct iov_iter source;
- unsigned long long start, len;
+ uoff_t start, len;
size_t part;
bool boundary = false;
@@ -149,8 +149,7 @@ static void netfs_retry_write_stream(struct netfs_io_request *wreq,
* and insert them after.
*/
do {
- subreq = netfs_alloc_subrequest(wreq);
- subreq->source = to->source;
+ subreq = netfs_alloc_subrequest(wreq, stream->source);
subreq->start = start;
subreq->stream_nr = to->stream_nr;
subreq->retry_count = 1;
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
index 6bb30543eff00..e7862f35b72c8 100644
--- a/fs/nfs/Kconfig
+++ b/fs/nfs/Kconfig
@@ -174,6 +174,7 @@ config NFS_FSCACHE
bool "Provide NFS client caching support"
depends on NFS_FS
select NETFS_SUPPORT
+ select NETFS_PGPRIV2
select FSCACHE
help
Say Y here if you want NFS data to be cached locally on disc through
diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h
index 4c91a019972b6..ee524c863fa9b 100644
--- a/include/linux/fscache-cache.h
+++ b/include/linux/fscache-cache.h
@@ -67,7 +67,7 @@ struct fscache_cache_ops {
/* Change the size of a data object */
void (*resize_cookie)(struct netfs_cache_resources *cres,
- loff_t new_size);
+ uoff_t new_size);
/* Invalidate an object */
bool (*invalidate_cookie)(struct fscache_cookie *cookie);
diff --git a/include/linux/fscache.h b/include/linux/fscache.h
index 58fdb9605425d..e19fca38382b9 100644
--- a/include/linux/fscache.h
+++ b/include/linux/fscache.h
@@ -112,7 +112,7 @@ struct fscache_cookie {
struct list_head proc_link; /* Link in proc list */
struct list_head commit_link; /* Link in commit queue */
struct work_struct work; /* Commit/relinq/withdraw work */
- loff_t object_size; /* Size of the netfs object */
+ uoff_t object_size; /* Size of the netfs object */
unsigned long unused_at; /* Time at which unused (jiffies) */
unsigned long flags;
#define FSCACHE_COOKIE_RELINQUISHED 0 /* T if cookie has been relinquished */
@@ -163,22 +163,22 @@ extern struct fscache_cookie *__fscache_acquire_cookie(
u8,
const void *, size_t,
const void *, size_t,
- loff_t);
+ uoff_t);
extern void __fscache_use_cookie(struct fscache_cookie *, bool);
-extern void __fscache_unuse_cookie(struct fscache_cookie *, const void *, const loff_t *);
+extern void __fscache_unuse_cookie(struct fscache_cookie *, const void *, const uoff_t *);
extern void __fscache_relinquish_cookie(struct fscache_cookie *, bool);
-extern void __fscache_resize_cookie(struct fscache_cookie *, loff_t);
-extern void __fscache_invalidate(struct fscache_cookie *, const void *, loff_t, unsigned int);
+extern void __fscache_resize_cookie(struct fscache_cookie *, uoff_t);
+extern void __fscache_invalidate(struct fscache_cookie *, const void *, uoff_t, unsigned int);
extern int __fscache_begin_read_operation(struct netfs_cache_resources *, struct fscache_cookie *);
extern int __fscache_begin_write_operation(struct netfs_cache_resources *, struct fscache_cookie *);
void __fscache_write_to_cache(struct fscache_cookie *cookie,
struct address_space *mapping,
- loff_t start, size_t len, loff_t i_size,
+ uoff_t start, size_t len, uoff_t i_size,
netfs_io_terminated_t term_func,
void *term_func_priv,
bool using_pgpriv2, bool cond);
-extern void __fscache_clear_page_bits(struct address_space *, loff_t, size_t);
+extern void __fscache_clear_page_bits(struct address_space *, uoff_t, size_t);
/**
* fscache_acquire_volume - Register a volume as desiring caching services
@@ -249,7 +249,7 @@ struct fscache_cookie *fscache_acquire_cookie(struct fscache_volume *volume,
size_t index_key_len,
const void *aux_data,
size_t aux_data_len,
- loff_t object_size)
+ uoff_t object_size)
{
if (!fscache_volume_valid(volume))
return NULL;
@@ -286,7 +286,7 @@ static inline void fscache_use_cookie(struct fscache_cookie *cookie,
*/
static inline void fscache_unuse_cookie(struct fscache_cookie *cookie,
const void *aux_data,
- const loff_t *object_size)
+ const uoff_t *object_size)
{
if (fscache_cookie_valid(cookie))
__fscache_unuse_cookie(cookie, aux_data, object_size);
@@ -327,7 +327,7 @@ static inline void *fscache_get_aux(struct fscache_cookie *cookie)
*/
static inline
void fscache_update_aux(struct fscache_cookie *cookie,
- const void *aux_data, const loff_t *object_size)
+ const void *aux_data, const uoff_t *object_size)
{
void *p = fscache_get_aux(cookie);
@@ -343,7 +343,7 @@ extern atomic_t fscache_n_updates;
static inline
void __fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data,
- const loff_t *object_size)
+ const uoff_t *object_size)
{
#ifdef CONFIG_FSCACHE_STATS
atomic_inc(&fscache_n_updates);
@@ -369,7 +369,7 @@ void __fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data
*/
static inline
void fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data,
- const loff_t *object_size)
+ const uoff_t *object_size)
{
if (fscache_cookie_enabled(cookie))
__fscache_update_cookie(cookie, aux_data, object_size);
@@ -386,7 +386,7 @@ void fscache_update_cookie(struct fscache_cookie *cookie, const void *aux_data,
* description.
*/
static inline
-void fscache_resize_cookie(struct fscache_cookie *cookie, loff_t new_size)
+void fscache_resize_cookie(struct fscache_cookie *cookie, uoff_t new_size)
{
if (fscache_cookie_enabled(cookie))
__fscache_resize_cookie(cookie, new_size);
@@ -413,7 +413,7 @@ void fscache_resize_cookie(struct fscache_cookie *cookie, loff_t new_size)
*/
static inline
void fscache_invalidate(struct fscache_cookie *cookie,
- const void *aux_data, loff_t size, unsigned int flags)
+ const void *aux_data, uoff_t size, unsigned int flags)
{
if (fscache_cookie_enabled(cookie))
__fscache_invalidate(cookie, aux_data, size, flags);
@@ -502,7 +502,7 @@ static inline void fscache_end_operation(struct netfs_cache_resources *cres)
*/
static inline
int fscache_read(struct netfs_cache_resources *cres,
- loff_t start_pos,
+ uoff_t start_pos,
struct iov_iter *iter,
enum netfs_read_from_hole read_hole,
netfs_io_terminated_t term_func,
@@ -561,7 +561,7 @@ int fscache_begin_write_operation(struct netfs_cache_resources *cres,
*/
static inline
int fscache_write(struct netfs_cache_resources *cres,
- loff_t start_pos,
+ uoff_t start_pos,
struct iov_iter *iter,
netfs_io_terminated_t term_func,
void *term_func_priv)
@@ -581,7 +581,7 @@ int fscache_write(struct netfs_cache_resources *cres,
* waiting.
*/
static inline void fscache_clear_page_bits(struct address_space *mapping,
- loff_t start, size_t len,
+ uoff_t start, size_t len,
bool caching)
{
if (caching)
@@ -615,7 +615,7 @@ static inline void fscache_clear_page_bits(struct address_space *mapping,
*/
static inline void fscache_write_to_cache(struct fscache_cookie *cookie,
struct address_space *mapping,
- loff_t start, size_t len, loff_t i_size,
+ uoff_t start, size_t len, uoff_t i_size,
netfs_io_terminated_t term_func,
void *term_func_priv,
bool using_pgpriv2, bool caching)
diff --git a/include/linux/netfs.h b/include/linux/netfs.h
index b4dd32863dd45..71fdd6ef43a7d 100644
--- a/include/linux/netfs.h
+++ b/include/linux/netfs.h
@@ -62,8 +62,8 @@ struct netfs_inode {
struct fscache_cookie *cache;
#endif
struct list_head wb_queue; /* Queue of processes wanting to do writeback */
- loff_t _remote_i_size; /* Size of the remote file */
- loff_t _zero_point; /* Size after which we assume there's no data
+ uoff_t _remote_i_size; /* Size of the remote file */
+ uoff_t _zero_point; /* Size after which we assume there's no data
* on the server */
spinlock_t lock; /* Lock covering wb_queue */
atomic_t io_count; /* Number of outstanding reqs */
@@ -142,7 +142,7 @@ struct netfs_io_stream {
void (*issue_write)(struct netfs_io_subrequest *subreq);
/* Collection tracking */
struct list_head subrequests; /* Contributory I/O operations */
- unsigned long long collected_to; /* Position we've collected results to */
+ uoff_t collected_to; /* Position we've collected results to */
size_t transferred; /* The amount transferred from this stream */
unsigned short error; /* Aggregate error for the stream */
enum netfs_io_source source; /* Where to read from/write to */
@@ -161,7 +161,8 @@ struct netfs_cache_resources {
const struct netfs_cache_ops *ops;
void *cache_priv;
void *cache_priv2;
- unsigned int debug_id; /* Cookie debug ID */
+ unsigned int cookie_id; /* Cache cookie debug ID */
+ unsigned int object_id; /* Cache object debug ID */
unsigned int inval_counter; /* object->inval_counter at begin_op */
};
@@ -177,7 +178,7 @@ struct netfs_io_subrequest {
struct work_struct work;
struct list_head rreq_link; /* Link in rreq->subrequests */
struct iov_iter io_iter; /* Iterator for this subrequest */
- unsigned long long start; /* Where to start the I/O */
+ uoff_t start; /* Where to start the I/O */
size_t len; /* Size of the I/O */
size_t transferred; /* Amount of data transferred */
refcount_t ref;
@@ -208,7 +209,6 @@ enum netfs_io_origin {
NETFS_DIO_READ, /* This is a direct I/O read */
NETFS_WRITEBACK, /* This write was triggered by writepages */
NETFS_WRITEBACK_SINGLE, /* This monolithic write was triggered by writepages */
- NETFS_WRITETHROUGH, /* This write was made by netfs_perform_write() */
NETFS_UNBUFFERED_WRITE, /* This is an unbuffered write */
NETFS_DIO_WRITE, /* This is a direct I/O write */
NETFS_PGPRIV2_COPY_TO_CACHE, /* [DEPRECATED] This is writing read data to the cache */
@@ -243,17 +243,17 @@ struct netfs_io_request {
void *netfs_priv; /* Private data for the netfs */
void *netfs_priv2; /* Private data for the netfs */
struct bio_vec *direct_bv; /* DIO buffer list (when handling iovec-iter) */
- unsigned long long submitted; /* Amount submitted for I/O so far */
- unsigned long long len; /* Length of the request */
+ uoff_t submitted; /* Amount submitted for I/O so far */
+ uoff_t len; /* Length of the request */
size_t transferred; /* Amount to be indicated as transferred */
size_t progress_at; /* Report read progress when hit this much read */
long error; /* 0 or error that occurred */
- unsigned long long i_size; /* Size of the file */
- unsigned long long start; /* Start position */
+ uoff_t i_size; /* Size of the file */
+ uoff_t start; /* Start position */
atomic64_t issued_to; /* Write issuer folio cursor */
- unsigned long long collected_to; /* Point we've collected to */
- unsigned long long cleaned_to; /* Position we've cleaned folios to */
- unsigned long long abandon_to; /* Position to abandon folios to */
+ uoff_t collected_to; /* Point we've collected to */
+ uoff_t cleaned_to; /* Position we've cleaned folios to */
+ uoff_t abandon_to; /* Position to abandon folios to */
const struct folio *no_unlock_folio; /* Don't unlock this folio after read */
gfp_t gfp; /* GFP flags to use */
unsigned int direct_bv_count; /* Number of elements in direct_bv[] */
@@ -279,8 +279,10 @@ struct netfs_io_request {
#define NETFS_RREQ_UPLOAD_TO_SERVER 11 /* Need to write to the server */
#define NETFS_RREQ_USE_IO_ITER 12 /* Use ->io_iter rather than ->i_pages */
#define NETFS_RREQ_NEED_PUT_RA_REFS 17 /* Need to put the folio refs RA gave us */
+#ifdef CONFIG_NETFS_PGPRIV2
#define NETFS_RREQ_USE_PGPRIV2 31 /* [DEPRECATED] Use PG_private_2 to mark
* write to cache on read */
+#endif
const struct netfs_request_ops *netfs_ops;
};
@@ -299,12 +301,12 @@ struct netfs_request_ops {
int (*prepare_read)(struct netfs_io_subrequest *subreq);
void (*issue_read)(struct netfs_io_subrequest *subreq);
bool (*is_still_valid)(struct netfs_io_request *rreq);
- int (*check_write_begin)(struct file *file, loff_t pos, unsigned len,
+ int (*check_write_begin)(struct file *file, uoff_t pos, unsigned len,
struct folio **foliop, void **_fsdata);
void (*done)(struct netfs_io_request *rreq);
/* Modification handling */
- void (*update_i_size)(struct inode *inode, loff_t i_size);
+ void (*update_i_size)(struct inode *inode, uoff_t i_size);
void (*post_modify)(struct inode *inode);
/* Write request handling */
@@ -332,7 +334,7 @@ struct netfs_cache_ops {
/* Read data from the cache */
int (*read)(struct netfs_cache_resources *cres,
- loff_t start_pos,
+ uoff_t start_pos,
struct iov_iter *iter,
enum netfs_read_from_hole read_hole,
netfs_io_terminated_t term_func,
@@ -340,7 +342,7 @@ struct netfs_cache_ops {
/* Write data to the cache */
int (*write)(struct netfs_cache_resources *cres,
- loff_t start_pos,
+ uoff_t start_pos,
struct iov_iter *iter,
netfs_io_terminated_t term_func,
void *term_func_priv);
@@ -350,15 +352,15 @@ struct netfs_cache_ops {
/* Expand readahead request */
void (*expand_readahead)(struct netfs_cache_resources *cres,
- unsigned long long *_start,
- unsigned long long *_len,
- unsigned long long i_size);
+ uoff_t *_start,
+ uoff_t *_len,
+ uoff_t i_size);
/* Prepare a read operation, shortening it to a cached/uncached
* boundary as appropriate.
*/
enum netfs_io_source (*prepare_read)(struct netfs_io_subrequest *subreq,
- unsigned long long i_size);
+ uoff_t i_size);
/* Prepare a write subrequest, working out if we're allowed to do it
* and finding out the maximum amount of data to gather before
@@ -371,15 +373,15 @@ struct netfs_cache_ops {
* actually do.
*/
int (*prepare_write)(struct netfs_cache_resources *cres,
- loff_t *_start, size_t *_len, size_t upper_len,
- loff_t i_size, bool no_space_allocated_yet);
+ uoff_t *_start, size_t *_len, size_t upper_len,
+ uoff_t i_size, bool no_space_allocated_yet);
/* Query the occupancy of the cache in a region, returning where the
* next chunk of data starts and how long it is.
*/
int (*query_occupancy)(struct netfs_cache_resources *cres,
- loff_t start, size_t len, size_t granularity,
- loff_t *_data_start, size_t *_data_len);
+ uoff_t start, size_t len, size_t granularity,
+ uoff_t *_data_start, size_t *_data_len);
};
/* High-level read API. */
@@ -410,7 +412,7 @@ struct readahead_control;
void netfs_readahead(struct readahead_control *);
int netfs_read_folio(struct file *, struct folio *);
int netfs_write_begin(struct netfs_inode *, struct file *,
- struct address_space *, loff_t pos, unsigned int len,
+ struct address_space *, uoff_t pos, unsigned int len,
struct folio **, void **fsdata);
int netfs_writepages(struct address_space *mapping,
struct writeback_control *wbc);
@@ -488,10 +490,10 @@ static inline struct netfs_inode *netfs_inode(struct inode *inode)
* cmpxchg8b without the need of the lock prefix). For SMP compiles and 64bit
* archs it makes no difference if preempt is enabled or not.
*/
-static inline unsigned long long netfs_read_remote_i_size(const struct inode *inode)
+static inline uoff_t netfs_read_remote_i_size(const struct inode *inode)
{
const struct netfs_inode *ictx = container_of(inode, struct netfs_inode, inode);
- unsigned long long remote_i_size;
+ uoff_t remote_i_size;
#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
unsigned int seq;
@@ -526,7 +528,7 @@ static inline unsigned long long netfs_read_remote_i_size(const struct inode *in
* spinning forever.
*/
static inline void netfs_write_remote_i_size(struct inode *inode,
- unsigned long long remote_i_size)
+ uoff_t remote_i_size)
{
struct netfs_inode *ictx = netfs_inode(inode);
@@ -563,10 +565,10 @@ static inline void netfs_write_remote_i_size(struct inode *inode,
* cmpxchg8b without the need of the lock prefix). For SMP compiles and 64bit
* archs it makes no difference if preempt is enabled or not.
*/
-static inline unsigned long long netfs_read_zero_point(const struct inode *inode)
+static inline uoff_t netfs_read_zero_point(const struct inode *inode)
{
struct netfs_inode *ictx = container_of(inode, struct netfs_inode, inode);
- unsigned long long zero_point;
+ uoff_t zero_point;
#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
unsigned int seq;
@@ -601,7 +603,7 @@ static inline unsigned long long netfs_read_zero_point(const struct inode *inode
* forever.
*/
static inline void netfs_write_zero_point(struct inode *inode,
- unsigned long long zero_point)
+ uoff_t zero_point)
{
struct netfs_inode *ictx = netfs_inode(inode);
@@ -642,9 +644,9 @@ static inline void netfs_write_zero_point(struct inode *inode,
* archs it makes no difference if preempt is enabled or not.
*/
static inline void netfs_read_sizes(const struct inode *inode,
- unsigned long long *i_size,
- unsigned long long *remote_i_size,
- unsigned long long *zero_point)
+ uoff_t *i_size,
+ uoff_t *remote_i_size,
+ uoff_t *zero_point)
{
const struct netfs_inode *ictx = container_of(inode, struct netfs_inode, inode);
#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
@@ -690,9 +692,9 @@ static inline void netfs_read_sizes(const struct inode *inode,
* forever.
*/
static inline void netfs_write_sizes(struct inode *inode,
- unsigned long long i_size,
- unsigned long long remote_i_size,
- unsigned long long zero_point)
+ uoff_t i_size,
+ uoff_t remote_i_size,
+ uoff_t zero_point)
{
struct netfs_inode *ictx = netfs_inode(inode);
@@ -760,7 +762,7 @@ static inline void netfs_inode_init(struct netfs_inode *ctx,
* Inform the netfs lib that a file got resized so that it can adjust its state.
*/
static inline void netfs_resize_file(struct netfs_inode *ictx,
- unsigned long long new_i_size,
+ uoff_t new_i_size,
bool changed_on_server)
{
#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
diff --git a/include/trace/events/cachefiles.h b/include/trace/events/cachefiles.h
index e3101410e8b2d..1938d51a94594 100644
--- a/include/trace/events/cachefiles.h
+++ b/include/trace/events/cachefiles.h
@@ -449,7 +449,7 @@ TRACE_EVENT(cachefiles_vol_coherency,
TRACE_EVENT(cachefiles_prep_read,
TP_PROTO(struct cachefiles_object *obj,
- loff_t start,
+ uoff_t start,
size_t len,
unsigned short flags,
enum netfs_io_source source,
@@ -464,7 +464,7 @@ TRACE_EVENT(cachefiles_prep_read,
__field(enum netfs_io_source, source)
__field(enum cachefiles_prepare_read_trace, why)
__field(size_t, len)
- __field(loff_t, start)
+ __field(uoff_t, start)
__field(unsigned int, netfs_inode)
__field(unsigned int, cache_inode)
),
@@ -492,16 +492,16 @@ TRACE_EVENT(cachefiles_prep_read,
TRACE_EVENT(cachefiles_read,
TP_PROTO(struct cachefiles_object *obj,
struct inode *backer,
- loff_t start,
+ uoff_t start,
size_t len),
TP_ARGS(obj, backer, start, len),
TP_STRUCT__entry(
- __field(unsigned int, obj)
- __field(unsigned int, backer)
- __field(size_t, len)
- __field(loff_t, start)
+ __field(unsigned int, obj)
+ __field(unsigned int, backer)
+ __field(size_t, len)
+ __field(uoff_t, start)
),
TP_fast_assign(
@@ -521,16 +521,16 @@ TRACE_EVENT(cachefiles_read,
TRACE_EVENT(cachefiles_write,
TP_PROTO(struct cachefiles_object *obj,
struct inode *backer,
- loff_t start,
+ uoff_t start,
size_t len),
TP_ARGS(obj, backer, start, len),
TP_STRUCT__entry(
- __field(unsigned int, obj)
- __field(unsigned int, backer)
- __field(size_t, len)
- __field(loff_t, start)
+ __field(unsigned int, obj)
+ __field(unsigned int, backer)
+ __field(size_t, len)
+ __field(uoff_t, start)
),
TP_fast_assign(
@@ -549,7 +549,7 @@ TRACE_EVENT(cachefiles_write,
TRACE_EVENT(cachefiles_trunc,
TP_PROTO(struct cachefiles_object *obj, struct inode *backer,
- loff_t from, loff_t to, enum cachefiles_trunc_trace why),
+ uoff_t from, uoff_t to, enum cachefiles_trunc_trace why),
TP_ARGS(obj, backer, from, to, why),
@@ -557,8 +557,8 @@ TRACE_EVENT(cachefiles_trunc,
__field(unsigned int, obj)
__field(unsigned int, backer)
__field(enum cachefiles_trunc_trace, why)
- __field(loff_t, from)
- __field(loff_t, to)
+ __field(uoff_t, from)
+ __field(uoff_t, to)
),
TP_fast_assign(
diff --git a/include/trace/events/fscache.h b/include/trace/events/fscache.h
index f1a73aa83fbbf..8735d428ebd9b 100644
--- a/include/trace/events/fscache.h
+++ b/include/trace/events/fscache.h
@@ -460,13 +460,13 @@ TRACE_EVENT(fscache_relinquish,
);
TRACE_EVENT(fscache_invalidate,
- TP_PROTO(struct fscache_cookie *cookie, loff_t new_size),
+ TP_PROTO(struct fscache_cookie *cookie, uoff_t new_size),
TP_ARGS(cookie, new_size),
TP_STRUCT__entry(
__field(unsigned int, cookie )
- __field(loff_t, new_size )
+ __field(uoff_t, new_size )
),
TP_fast_assign(
@@ -479,14 +479,14 @@ TRACE_EVENT(fscache_invalidate,
);
TRACE_EVENT(fscache_resize,
- TP_PROTO(struct fscache_cookie *cookie, loff_t new_size),
+ TP_PROTO(struct fscache_cookie *cookie, uoff_t new_size),
TP_ARGS(cookie, new_size),
TP_STRUCT__entry(
__field(unsigned int, cookie )
- __field(loff_t, old_size )
- __field(loff_t, new_size )
+ __field(uoff_t, old_size )
+ __field(uoff_t, new_size )
),
TP_fast_assign(
diff --git a/include/trace/events/netfs.h b/include/trace/events/netfs.h
index 3fec3e8f91c85..303309be253f2 100644
--- a/include/trace/events/netfs.h
+++ b/include/trace/events/netfs.h
@@ -30,8 +30,7 @@
EM(netfs_write_trace_dio_write, "DIO-WRITE") \
EM(netfs_write_trace_unbuffered_write, "UNB-WRITE") \
EM(netfs_write_trace_writeback, "WRITEBACK") \
- EM(netfs_write_trace_writeback_single, "WB-SINGLE") \
- E_(netfs_write_trace_writethrough, "WRITETHRU")
+ E_(netfs_write_trace_writeback_single, "WB-SINGLE")
#define netfs_rreq_origins \
EM(NETFS_READAHEAD, "RA") \
@@ -43,12 +42,12 @@
EM(NETFS_DIO_READ, "DR") \
EM(NETFS_WRITEBACK, "WB") \
EM(NETFS_WRITEBACK_SINGLE, "W1") \
- EM(NETFS_WRITETHROUGH, "WT") \
EM(NETFS_UNBUFFERED_WRITE, "UW") \
EM(NETFS_DIO_WRITE, "DW") \
E_(NETFS_PGPRIV2_COPY_TO_CACHE, "2C")
#define netfs_rreq_traces \
+ EM(netfs_rreq_trace_all_queued, "ALL-Q ") \
EM(netfs_rreq_trace_assess, "ASSESS ") \
EM(netfs_rreq_trace_collect, "COLLECT") \
EM(netfs_rreq_trace_complete, "COMPLET") \
@@ -194,11 +193,11 @@
EM(netfs_folio_trace_alloc_buffer, "alloc-buf") \
EM(netfs_folio_trace_cancel_copy, "cancel-copy") \
EM(netfs_folio_trace_cancel_store, "cancel-store") \
- EM(netfs_folio_trace_clear, "clear") \
- EM(netfs_folio_trace_clear_cc, "clear-cc") \
- EM(netfs_folio_trace_clear_g, "clear-g") \
- EM(netfs_folio_trace_clear_s, "clear-s") \
EM(netfs_folio_trace_end_copy, "end-copy") \
+ EM(netfs_folio_trace_endwb, "endwb") \
+ EM(netfs_folio_trace_endwb_cc, "endwb-cc") \
+ EM(netfs_folio_trace_endwb_g, "endwb-g") \
+ EM(netfs_folio_trace_endwb_s, "endwb-s") \
EM(netfs_folio_trace_filled_gaps, "filled-gaps") \
EM(netfs_folio_trace_invalidate_all, "inval-all") \
EM(netfs_folio_trace_invalidate_front, "inval-front") \
@@ -223,9 +222,7 @@
EM(netfs_folio_trace_sched_copy, "sched-copy") \
EM(netfs_folio_trace_store, "store") \
EM(netfs_folio_trace_store_copy, "store-copy") \
- EM(netfs_folio_trace_store_plus, "store+") \
- EM(netfs_folio_trace_wthru, "wthru") \
- E_(netfs_folio_trace_wthru_plus, "wthru+")
+ E_(netfs_folio_trace_store_plus, "store+")
#define netfs_collect_contig_traces \
EM(netfs_contig_trace_collect, "Collect") \
@@ -301,7 +298,7 @@ netfs_folioq_traces;
TRACE_EVENT(netfs_read,
TP_PROTO(struct netfs_io_request *rreq,
- loff_t start, size_t len,
+ uoff_t start, size_t len,
enum netfs_read_trace what),
TP_ARGS(rreq, start, len, what),
@@ -309,8 +306,9 @@ TRACE_EVENT(netfs_read,
TP_STRUCT__entry(
__field(unsigned int, rreq)
__field(unsigned int, cookie)
- __field(loff_t, i_size)
- __field(loff_t, start)
+ __field(unsigned int, object)
+ __field(uoff_t, i_size)
+ __field(uoff_t, start)
__field(size_t, len)
__field(enum netfs_read_trace, what)
__field(u64, netfs_inode)
@@ -318,7 +316,8 @@ TRACE_EVENT(netfs_read,
TP_fast_assign(
__entry->rreq = rreq->debug_id;
- __entry->cookie = rreq->cache_resources.debug_id;
+ __entry->cookie = rreq->cache_resources.cookie_id;
+ __entry->object = rreq->cache_resources.object_id;
__entry->i_size = rreq->i_size;
__entry->start = start;
__entry->len = len;
@@ -326,10 +325,10 @@ TRACE_EVENT(netfs_read,
__entry->netfs_inode = rreq->inode->i_ino;
),
- TP_printk("R=%08x %s c=%08x ni=%llx s=%llx l=%zx sz=%llx",
+ TP_printk("R=%08x %s c=%08x o=%08x ni=%llx s=%llx l=%zx sz=%llx",
__entry->rreq,
__print_symbolic(__entry->what, netfs_read_traces),
- __entry->cookie,
+ __entry->cookie, __entry->object,
__entry->netfs_inode,
__entry->start, __entry->len, __entry->i_size)
);
@@ -377,7 +376,7 @@ TRACE_EVENT(netfs_sreq,
__field(u8, slot)
__field(size_t, len)
__field(size_t, transferred)
- __field(loff_t, start)
+ __field(uoff_t, start)
),
TP_fast_assign(
@@ -418,7 +417,7 @@ TRACE_EVENT(netfs_failure,
__field(enum netfs_failure, what)
__field(size_t, len)
__field(size_t, transferred)
- __field(loff_t, start)
+ __field(uoff_t, start)
),
TP_fast_assign(
@@ -501,6 +500,7 @@ TRACE_EVENT(netfs_folio,
TP_STRUCT__entry(
__field(u64, ino)
__field(pgoff_t, index)
+ __field(unsigned long, pfn)
__field(unsigned int, nr)
__field(enum netfs_folio_trace, why)
),
@@ -511,9 +511,11 @@ TRACE_EVENT(netfs_folio,
__entry->why = why;
__entry->index = folio->index;
__entry->nr = folio_nr_pages(folio);
+ __entry->pfn = folio_pfn(folio);
),
- TP_printk("i=%05llx ix=%05lx-%05lx %s",
+ TP_printk("p=%lx i=%05llx ix=%05lx-%05lx %s",
+ __entry->pfn,
__entry->ino, __entry->index, __entry->index + __entry->nr - 1,
__print_symbolic(__entry->why, netfs_folio_traces))
);
@@ -524,10 +526,10 @@ TRACE_EVENT(netfs_write_iter,
TP_ARGS(iocb, from),
TP_STRUCT__entry(
- __field(unsigned long long, start)
- __field(size_t, len)
- __field(unsigned int, flags)
- __field(unsigned int, ino)
+ __field(uoff_t, start)
+ __field(size_t, len)
+ __field(unsigned int, flags)
+ __field(unsigned int, ino)
),
TP_fast_assign(
@@ -550,27 +552,27 @@ TRACE_EVENT(netfs_write,
TP_STRUCT__entry(
__field(unsigned int, wreq)
__field(unsigned int, cookie)
+ __field(unsigned int, object)
__field(unsigned int, ino)
__field(enum netfs_write_trace, what)
- __field(unsigned long long, start)
- __field(unsigned long long, len)
+ __field(uoff_t, start)
+ __field(uoff_t, len)
),
TP_fast_assign(
- struct netfs_inode *__ctx = netfs_inode(wreq->inode);
- struct fscache_cookie *__cookie = netfs_i_cookie(__ctx);
__entry->wreq = wreq->debug_id;
- __entry->cookie = __cookie ? __cookie->debug_id : 0;
+ __entry->cookie = wreq->cache_resources.cookie_id;
+ __entry->object = wreq->cache_resources.object_id;
__entry->ino = wreq->inode->i_ino;
__entry->what = what;
__entry->start = wreq->start;
__entry->len = wreq->len;
),
- TP_printk("R=%08x %s c=%08x i=%x by=%llx-%llx",
+ TP_printk("R=%08x %s c=%08x o=%08x i=%x by=%llx-%llx",
__entry->wreq,
__print_symbolic(__entry->what, netfs_write_traces),
- __entry->cookie,
+ __entry->cookie, __entry->object,
__entry->ino,
__entry->start, __entry->start + __entry->len - 1)
);
@@ -582,25 +584,26 @@ TRACE_EVENT(netfs_copy2cache,
TP_ARGS(rreq, creq),
TP_STRUCT__entry(
- __field(unsigned int, rreq)
- __field(unsigned int, creq)
- __field(unsigned int, cookie)
- __field(unsigned int, ino)
+ __field(unsigned int, rreq)
+ __field(unsigned int, creq)
+ __field(unsigned int, cookie)
+ __field(unsigned int, object)
+ __field(unsigned int, ino)
),
TP_fast_assign(
- struct netfs_inode *__ctx = netfs_inode(rreq->inode);
- struct fscache_cookie *__cookie = netfs_i_cookie(__ctx);
__entry->rreq = rreq->debug_id;
__entry->creq = creq->debug_id;
- __entry->cookie = __cookie ? __cookie->debug_id : 0;
+ __entry->cookie = rreq->cache_resources.cookie_id;
+ __entry->object = rreq->cache_resources.object_id;
__entry->ino = rreq->inode->i_ino;
),
- TP_printk("R=%08x CR=%08x c=%08x i=%x ",
+ TP_printk("R=%08x CR=%08x c=%08x o=%08x i=%x ",
__entry->rreq,
__entry->creq,
__entry->cookie,
+ __entry->object,
__entry->ino)
);
@@ -610,10 +613,10 @@ TRACE_EVENT(netfs_collect,
TP_ARGS(wreq),
TP_STRUCT__entry(
- __field(unsigned int, wreq)
- __field(unsigned int, len)
- __field(unsigned long long, transferred)
- __field(unsigned long long, start)
+ __field(unsigned int, wreq)
+ __field(unsigned int, len)
+ __field(uoff_t, transferred)
+ __field(uoff_t, start)
),
TP_fast_assign(
@@ -636,12 +639,12 @@ TRACE_EVENT(netfs_collect_sreq,
TP_ARGS(wreq, subreq),
TP_STRUCT__entry(
- __field(unsigned int, wreq)
- __field(unsigned int, subreq)
- __field(unsigned int, stream)
- __field(unsigned int, len)
- __field(unsigned int, transferred)
- __field(unsigned long long, start)
+ __field(unsigned int, wreq)
+ __field(unsigned int, subreq)
+ __field(unsigned int, stream)
+ __field(unsigned int, len)
+ __field(unsigned int, transferred)
+ __field(uoff_t, start)
),
TP_fast_assign(
@@ -660,37 +663,30 @@ TRACE_EVENT(netfs_collect_sreq,
TRACE_EVENT(netfs_collect_folio,
TP_PROTO(const struct netfs_io_request *wreq,
- const struct folio *folio,
- unsigned long long fend,
- unsigned long long collected_to),
+ const struct folio *folio),
- TP_ARGS(wreq, folio, fend, collected_to),
+ TP_ARGS(wreq, folio),
TP_STRUCT__entry(
__field(unsigned int, wreq)
__field(unsigned long, index)
- __field(unsigned long long, fend)
- __field(unsigned long long, cleaned_to)
- __field(unsigned long long, collected_to)
+ __field(unsigned int, nr)
),
TP_fast_assign(
__entry->wreq = wreq->debug_id;
__entry->index = folio->index;
- __entry->fend = fend;
- __entry->cleaned_to = wreq->cleaned_to;
- __entry->collected_to = collected_to;
+ __entry->nr = folio_nr_pages(folio);
),
- TP_printk("R=%08x ix=%05lx r=%llx-%llx t=%llx/%llx",
+ TP_printk("R=%08x ix=%05lx-%05lx",
__entry->wreq, __entry->index,
- (unsigned long long)__entry->index * PAGE_SIZE, __entry->fend,
- __entry->cleaned_to, __entry->collected_to)
+ __entry->index + __entry->nr - 1)
);
TRACE_EVENT(netfs_collect_state,
TP_PROTO(const struct netfs_io_request *wreq,
- unsigned long long collected_to,
+ uoff_t collected_to,
unsigned int notes),
TP_ARGS(wreq, collected_to, notes),
@@ -698,8 +694,8 @@ TRACE_EVENT(netfs_collect_state,
TP_STRUCT__entry(
__field(unsigned int, wreq)
__field(unsigned int, notes)
- __field(unsigned long long, collected_to)
- __field(unsigned long long, cleaned_to)
+ __field(uoff_t, collected_to)
+ __field(uoff_t, cleaned_to)
),
TP_fast_assign(
@@ -718,7 +714,7 @@ TRACE_EVENT(netfs_collect_state,
TRACE_EVENT(netfs_collect_gap,
TP_PROTO(const struct netfs_io_request *wreq,
const struct netfs_io_stream *stream,
- unsigned long long jump_to, char type),
+ uoff_t jump_to, char type),
TP_ARGS(wreq, stream, jump_to, type),
@@ -726,8 +722,8 @@ TRACE_EVENT(netfs_collect_gap,
__field(unsigned int, wreq)
__field(unsigned char, stream)
__field(unsigned char, type)
- __field(unsigned long long, from)
- __field(unsigned long long, to)
+ __field(uoff_t, from)
+ __field(uoff_t, to)
),
TP_fast_assign(
@@ -752,8 +748,8 @@ TRACE_EVENT(netfs_collect_stream,
TP_STRUCT__entry(
__field(unsigned int, wreq)
__field(unsigned char, stream)
- __field(unsigned long long, collected_to)
- __field(unsigned long long, issued_to)
+ __field(uoff_t, collected_to)
+ __field(uoff_t, issued_to)
),
TP_fast_assign(
|
| 17/3 | 2026/09/09 08:20 | llm | kmsan-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 37100 output: 38 thoughts: 1252 Thoughts: **Analyzing the Patch for Uninitialized Memory Risks** Okay, let's dive into this patch and see if it introduces any uninitialized memory vulnerabilities that would necessitate a dedicated KMSAN fuzzing session. I need to figure out if we've got a "NeedsKMSAN = true" situation here. First, I need to understand the scope of the changes. It seems this patch is primarily about type conversions for file offsets and sizes, moving from `loff_t`/`unsigned long long` to `uoff_t` across multiple filesystems and related include files. It also looks like they're removing writethrough support in netfs. That's a significant simplification, which *could* reduce complexity, but I need to make sure it doesn't leave any gaps. Additionally, it seems to make `read_pgpriv2.c` conditional, and adds some initializations and new fields in a couple of places. I see helper functions being introduced and some tracepoint updates. This needs a methodical check. Now, let's start poking around for potential uninitialized reads. My gut feeling is that the most likely area for subtle problems lies in the new code, or around changes in existing structures. I'm focused on potential uninitialized reads or information leaks. I want to look very carefully at `netfs_alloc_subrequest`, and also at the `netfs_cache_resources` structure and any function using it. Looking at `netfs_alloc_subrequest` in `fs/netfs/objects.c`, I see a clear `memset(subreq, 0, sizeof(*subreq));` right at the beginning of allocation, which is good. That zeroes out the structure, making the chance of uninitialized reads very small from the initial allocation. The fields set after that seem okay. I feel reasonably confident about that function's safety. Now, let's examine `netfs_cache_resources` in `include/linux/netfs.h` and the functions that use it. In `fs/netfs/fscache_io.c`, `fscache_begin_operation` has initialization of the fields in `netfs_cache_resources`. Then, `cachefiles_begin_operation` in `fs/cachefiles/io.c` sets a few more fields. Also, trace events in `netfs_read` and `netfs_write` read `cookie_id` and `object_id` from the `cache_resources` field of the `rreq` structure. I need to trace where the `rreq` struct is allocated to ensure those fields are initialized correctly. I need to make sure the flow of control is correct; there should be no path where the fields are read before being written. So, now, let's look at `netfs_alloc_request` in `fs/netfs/objects.c`, which is where `rreq` is allocated. It looks like the `netfs_cache_resources` is getting initialized in the various begin_operation functions. I need to verify all code paths. Right now, this doesn't seem to be an uninitialized memory issue, at least not an obvious one. I can't be certain until I have checked all code paths, but, for now, the probability seems low. I don't see any obvious issues, and the use of `memset` and explicit initialization seem solid. |
| 18/3 | 2026/09/09 08:20 | tool | grepper |
0mArgs:{
"Expression": "struct netfs_io_request \\*netfs_alloc_request",
"PathPrefix": "fs/netfs"
}Results: {
"Output": "fs/netfs/internal.h=82=void netfs_wait_for_put_ra_refs(struct netfs_io_request *rreq);\n--\nfs/netfs/internal.h-86- */\nfs/netfs/internal.h:87:struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,\nfs/netfs/internal.h-88-\t\t\t\t\t struct file *file,\n--\nfs/netfs/objects.c=12=static void netfs_free_request(struct work_struct *work);\n--\nfs/netfs/objects.c-16- */\nfs/netfs/objects.c:17:struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,\nfs/netfs/objects.c-18-\t\t\t\t\t struct file *file,\n"
} |
| 19/3 | 2026/09/09 08:20 | llm | kmsan-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 39337 output: 35 thoughts: 23 Thoughts: Here's my summary, as though I'm reading and thinking about the code: **Diving into `netfs_alloc_request`** Okay, let's get into the heart of this. The goal here is to understand the allocation process for requests within the `netfs` filesystem. I'm focusing on `netfs_alloc_request`, which I'm assuming is the critical function for creating these network filesystem requests. Let's see how it's done... Let's read `fs/netfs/objects.c` and understand the mechanics. I need to be sure I'm following the flow correctly. This is where the magic happens and I want to see how these requests are allocated for future processing. |
| 20/3 | 2026/09/09 08:20 | tool | read-file |
0mArgs:{
"File": "fs/netfs/objects.c",
"FirstLine": 17,
"LineCount": 60
}Results: {
"Contents": " 17:\tstruct netfs_io_request *netfs_alloc_request(struct address_space *mapping,\n 18:\t\t\t\t\t\t struct file *file,\n 19:\t\t\t\t\t\t uoff_t start, size_t len,\n 20:\t\t\t\t\t\t enum netfs_io_origin origin)\n 21:\t{\n 22:\t\tstatic atomic_t debug_ids;\n 23:\t\tstruct inode *inode = file ? file_inode(file) : mapping-\u003ehost;\n 24:\t\tstruct netfs_inode *ctx = netfs_inode(inode);\n 25:\t\tstruct netfs_io_request *rreq;\n 26:\t\tmempool_t *mempool = ctx-\u003eops-\u003erequest_pool ?: \u0026netfs_request_pool;\n 27:\t\tstruct kmem_cache *cache = mempool-\u003epool_data;\n 28:\t\tgfp_t gfp = GFP_KERNEL;\n 29:\t\tint ret;\n 30:\t\n 31:\t\t/* Writeback is part of memory reclaim and must not fail due to ENOMEM. */\n 32:\t\tif (origin == NETFS_WRITEBACK || origin == NETFS_WRITEBACK_SINGLE) {\n 33:\t\t\tgfp = GFP_NOFS; /* Allows use of mempools. */\n 34:\t\n 35:\t\t\trreq = mempool_alloc(mempool, gfp);\n 36:\t\t} else {\n 37:\t\t\trreq = mempool-\u003ealloc(gfp, mempool-\u003epool_data);\n 38:\t\t\tif (!rreq)\n 39:\t\t\t\treturn ERR_PTR(-ENOMEM);\n 40:\t\t}\n 41:\t\n 42:\t\tmemset(rreq, 0, kmem_cache_size(cache));\n 43:\t\tINIT_WORK(\u0026rreq-\u003ecleanup_work, netfs_free_request);\n 44:\t\trreq-\u003egfp\t\t= gfp;\n 45:\t\trreq-\u003estart\t\t= start;\n 46:\t\trreq-\u003ecollected_to\t= start;\n 47:\t\trreq-\u003ecleaned_to\t= start;\n 48:\t\trreq-\u003elen\t\t= len;\n 49:\t\trreq-\u003eprogress_at\t= 0;\n 50:\t\trreq-\u003eorigin\t\t= origin;\n 51:\t\trreq-\u003enetfs_ops\t\t= ctx-\u003eops;\n 52:\t\trreq-\u003emapping\t\t= mapping;\n 53:\t\trreq-\u003einode\t\t= inode;\n 54:\t\trreq-\u003ei_size\t\t= i_size_read(inode);\n 55:\t\trreq-\u003edebug_id\t\t= atomic_inc_return(\u0026debug_ids);\n 56:\t\trreq-\u003ewsize\t\t= INT_MAX;\n 57:\t\trreq-\u003eio_streams[0].sreq_max_len = ULONG_MAX;\n 58:\t\trreq-\u003eio_streams[0].sreq_max_segs = 0;\n 59:\t\tspin_lock_init(\u0026rreq-\u003elock);\n 60:\t\tinit_waitqueue_head(\u0026rreq-\u003ewaitq);\n 61:\t\trefcount_set(\u0026rreq-\u003eref, 2);\n 62:\t\n 63:\t\tfor (int s = 0; s \u003c NR_IO_STREAMS; s++) {\n 64:\t\t\tstruct netfs_io_stream *stream = \u0026rreq-\u003eio_streams[s];\n 65:\t\n 66:\t\t\tINIT_LIST_HEAD(\u0026stream-\u003esubrequests);\n 67:\t\t\tstream-\u003ecollected_to = rreq-\u003estart;\n 68:\t\t}\n 69:\t\n 70:\t\tif (origin == NETFS_READAHEAD ||\n 71:\t\t origin == NETFS_READPAGE ||\n 72:\t\t origin == NETFS_READ_GAPS ||\n 73:\t\t origin == NETFS_READ_SINGLE ||\n 74:\t\t origin == NETFS_READ_FOR_WRITE ||\n 75:\t\t origin == NETFS_UNBUFFERED_READ ||\n 76:\t\t origin == NETFS_DIO_READ) {\n"
} |
| 21/3 | 2026/09/09 08:20 | llm | kmsan-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 40581 output: 231 thoughts: 848 Thoughts: **My Assessment of the Patch's Safety** Okay, so `rreq` is being zeroed out using `memset`, which is good. That's the first thing I look for. Always good to start fresh. Now, I need to methodically check for potential vulnerabilities, especially related to user data leaks. The plan is always the same: let's scan for `copy_to_user`, `put_user`, socket options, sysctls, ioctls, or netlink messages. Basically, anything that touches userland. Alright, the file list is in. It looks like this patch touches files across a bunch of filesystems: 9p, afs, cachefiles, ceph, and netfs. Based on the file names, it looks like a lot of internal refactoring, so that's a good sign. But still, I need to be thorough. The changes appear to be focused on refactoring internal aspects of netfs and fscache. Specifically: 1. Converting `loff_t`/`unsigned long long` to `uoff_t`. This is a pretty straightforward type change. 2. Removing a dead write path (`NETFS_WRITETHROUGH`). This should be a removal of functionality, not introduction of new bugs. 3. Conditionalizing `read_pgpriv2.c` on a config option. Fine, as long as it behaves correctly based on the config. 4. Passing `source` directly to `netfs_alloc_subrequest` instead of assigning it later. Fine, that should actually simplify things and eliminate a potential source of error. And `rreq` is zeroed so no worries there. 5. Setting `cres->object_id` and updating tracepoints. Again, this should be fine. 6. Helper wrappers for `NETFS_RREQ_ALL_QUEUED`. More cleanup and organization, usually a good thing. Now, let's drill down and specifically look for uninitialized memory risks. Let's see... * No new uninitialized heap/stack memory allocations, that's important. * Everything is zeroed with `memset`. Excellent. Prevents those pesky uninitialized memory reads. * No data is being copied to userspace without being initialized. That's a huge win! * The control flow doesn't appear to be dependent on uninitialized variables or struct fields. Great. * Overall, the changes look like internal filesystem refactoring and cleanup. So, it doesn't appear that KMSAN is needed. This patch seems safe, KASAN and lockdep should be sufficient. I'll flag `NeedsKMSAN=false` and confirm everything is formatted correctly for `set-results`. |
| 22/3 | 2026/09/09 08:20 | tool | set-results |
0mArgs:{
"KMSANReasoning": "The patch performs internal refactoring within the netfs and fscache subsystems:\n1. Replaces offset and length types (`loff_t` and `unsigned long long`) with `uoff_t`.\n2. Removes the deprecated `NETFS_WRITETHROUGH` path and related writethrough tracking functions.\n3. Modularizes PG_private_2 read support behind `CONFIG_NETFS_PGPRIV2`.\n4. Refactors `netfs_alloc_subrequest` to pass `enum netfs_io_source` on allocation, where memory is explicitly zeroed via `memset`.\n5. Encapsulates `NETFS_RREQ_ALL_QUEUED` flag operations and updates tracepoints.\n\nNo uninitialized variables or memory buffers are introduced, and no data structures copied to user space or used in conditional logic are left uninitialized. Therefore, standard KASAN/lockdep testing is sufficient and a dedicated KMSAN session is not required.",
"NeedsKMSAN": false
}Results: {
"KMSANReasoning": "The patch performs internal refactoring within the netfs and fscache subsystems:\n1. Replaces offset and length types (`loff_t` and `unsigned long long`) with `uoff_t`.\n2. Removes the deprecated `NETFS_WRITETHROUGH` path and related writethrough tracking functions.\n3. Modularizes PG_private_2 read support behind `CONFIG_NETFS_PGPRIV2`.\n4. Refactors `netfs_alloc_subrequest` to pass `enum netfs_io_source` on allocation, where memory is explicitly zeroed via `memset`.\n5. Encapsulates `NETFS_RREQ_ALL_QUEUED` flag operations and updates tracepoints.\n\nNo uninitialized variables or memory buffers are introduced, and no data structures copied to user space or used in conditional logic are left uninitialized. Therefore, standard KASAN/lockdep testing is sufficient and a dedicated KMSAN session is not required.",
"NeedsKMSAN": false
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|