Skip to content

Commit c1ec4d7

Browse files
committed
netfs: Provide invalidate_folio and release_folio calls
Provide default invalidate_folio and release_folio calls. These will need to interact with invalidation correctly at some point. They will be needed if netfslib is to make use of folio->private for its own purposes. Signed-off-by: David Howells <dhowells@redhat.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> cc: linux-cachefs@redhat.com cc: linux-fsdevel@vger.kernel.org cc: linux-mm@kvack.org
1 parent a34847d commit c1ec4d7

6 files changed

Lines changed: 54 additions & 114 deletions

File tree

fs/9p/vfs_addr.c

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -88,35 +88,6 @@ const struct netfs_request_ops v9fs_req_ops = {
8888
.issue_read = v9fs_issue_read,
8989
};
9090

91-
/**
92-
* v9fs_release_folio - release the private state associated with a folio
93-
* @folio: The folio to be released
94-
* @gfp: The caller's allocation restrictions
95-
*
96-
* Returns true if the page can be released, false otherwise.
97-
*/
98-
99-
static bool v9fs_release_folio(struct folio *folio, gfp_t gfp)
100-
{
101-
if (folio_test_private(folio))
102-
return false;
103-
#ifdef CONFIG_9P_FSCACHE
104-
if (folio_test_fscache(folio)) {
105-
if (current_is_kswapd() || !(gfp & __GFP_FS))
106-
return false;
107-
folio_wait_fscache(folio);
108-
}
109-
fscache_note_page_release(v9fs_inode_cookie(V9FS_I(folio_inode(folio))));
110-
#endif
111-
return true;
112-
}
113-
114-
static void v9fs_invalidate_folio(struct folio *folio, size_t offset,
115-
size_t length)
116-
{
117-
folio_wait_fscache(folio);
118-
}
119-
12091
#ifdef CONFIG_9P_FSCACHE
12192
static void v9fs_write_to_cache_done(void *priv, ssize_t transferred_or_error,
12293
bool was_async)
@@ -324,8 +295,8 @@ const struct address_space_operations v9fs_addr_operations = {
324295
.writepage = v9fs_vfs_writepage,
325296
.write_begin = v9fs_write_begin,
326297
.write_end = v9fs_write_end,
327-
.release_folio = v9fs_release_folio,
328-
.invalidate_folio = v9fs_invalidate_folio,
298+
.release_folio = netfs_release_folio,
299+
.invalidate_folio = netfs_invalidate_folio,
329300
.launder_folio = v9fs_launder_folio,
330301
.direct_IO = v9fs_direct_IO,
331302
};

fs/afs/file.c

Lines changed: 4 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@
2020

2121
static int afs_file_mmap(struct file *file, struct vm_area_struct *vma);
2222
static int afs_symlink_read_folio(struct file *file, struct folio *folio);
23-
static void afs_invalidate_folio(struct folio *folio, size_t offset,
24-
size_t length);
25-
static bool afs_release_folio(struct folio *folio, gfp_t gfp_flags);
2623

2724
static ssize_t afs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter);
2825
static ssize_t afs_file_splice_read(struct file *in, loff_t *ppos,
@@ -57,8 +54,8 @@ const struct address_space_operations afs_file_aops = {
5754
.readahead = netfs_readahead,
5855
.dirty_folio = netfs_dirty_folio,
5956
.launder_folio = afs_launder_folio,
60-
.release_folio = afs_release_folio,
61-
.invalidate_folio = afs_invalidate_folio,
57+
.release_folio = netfs_release_folio,
58+
.invalidate_folio = netfs_invalidate_folio,
6259
.write_begin = afs_write_begin,
6360
.write_end = afs_write_end,
6461
.writepages = afs_writepages,
@@ -67,8 +64,8 @@ const struct address_space_operations afs_file_aops = {
6764

6865
const struct address_space_operations afs_symlink_aops = {
6966
.read_folio = afs_symlink_read_folio,
70-
.release_folio = afs_release_folio,
71-
.invalidate_folio = afs_invalidate_folio,
67+
.release_folio = netfs_release_folio,
68+
.invalidate_folio = netfs_invalidate_folio,
7269
.migrate_folio = filemap_migrate_folio,
7370
};
7471

@@ -386,48 +383,6 @@ const struct netfs_request_ops afs_req_ops = {
386383
.issue_read = afs_issue_read,
387384
};
388385

389-
/*
390-
* invalidate part or all of a page
391-
* - release a page and clean up its private data if offset is 0 (indicating
392-
* the entire page)
393-
*/
394-
static void afs_invalidate_folio(struct folio *folio, size_t offset,
395-
size_t length)
396-
{
397-
_enter("{%lu},%zu,%zu", folio->index, offset, length);
398-
399-
folio_wait_fscache(folio);
400-
_leave("");
401-
}
402-
403-
/*
404-
* release a page and clean up its private state if it's not busy
405-
* - return true if the page can now be released, false if not
406-
*/
407-
static bool afs_release_folio(struct folio *folio, gfp_t gfp)
408-
{
409-
struct afs_vnode *vnode = AFS_FS_I(folio_inode(folio));
410-
411-
_enter("{{%llx:%llu}[%lu],%lx},%x",
412-
vnode->fid.vid, vnode->fid.vnode, folio_index(folio), folio->flags,
413-
gfp);
414-
415-
/* deny if folio is being written to the cache and the caller hasn't
416-
* elected to wait */
417-
#ifdef CONFIG_AFS_FSCACHE
418-
if (folio_test_fscache(folio)) {
419-
if (current_is_kswapd() || !(gfp & __GFP_FS))
420-
return false;
421-
folio_wait_fscache(folio);
422-
}
423-
fscache_note_page_release(afs_vnode_cache(vnode));
424-
#endif
425-
426-
/* Indicate that the folio can be released */
427-
_leave(" = T");
428-
return true;
429-
}
430-
431386
static void afs_add_open_mmap(struct afs_vnode *vnode)
432387
{
433388
if (atomic_inc_return(&vnode->cb_nr_mmap) == 1) {

fs/ceph/addr.c

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -159,27 +159,7 @@ static void ceph_invalidate_folio(struct folio *folio, size_t offset,
159159
ceph_put_snap_context(snapc);
160160
}
161161

162-
folio_wait_fscache(folio);
163-
}
164-
165-
static bool ceph_release_folio(struct folio *folio, gfp_t gfp)
166-
{
167-
struct inode *inode = folio->mapping->host;
168-
struct ceph_client *cl = ceph_inode_to_client(inode);
169-
170-
doutc(cl, "%llx.%llx idx %lu (%sdirty)\n", ceph_vinop(inode),
171-
folio->index, folio_test_dirty(folio) ? "" : "not ");
172-
173-
if (folio_test_private(folio))
174-
return false;
175-
176-
if (folio_test_fscache(folio)) {
177-
if (current_is_kswapd() || !(gfp & __GFP_FS))
178-
return false;
179-
folio_wait_fscache(folio);
180-
}
181-
ceph_fscache_note_page_release(inode);
182-
return true;
162+
netfs_invalidate_folio(folio, offset, length);
183163
}
184164

185165
static void ceph_netfs_expand_readahead(struct netfs_io_request *rreq)
@@ -1585,7 +1565,7 @@ const struct address_space_operations ceph_aops = {
15851565
.write_end = ceph_write_end,
15861566
.dirty_folio = ceph_dirty_folio,
15871567
.invalidate_folio = ceph_invalidate_folio,
1588-
.release_folio = ceph_release_folio,
1568+
.release_folio = netfs_release_folio,
15891569
.direct_IO = noop_direct_IO,
15901570
};
15911571

fs/ceph/cache.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,6 @@ static inline bool ceph_is_cache_enabled(struct inode *inode)
5656
return fscache_cookie_enabled(ceph_fscache_cookie(ceph_inode(inode)));
5757
}
5858

59-
static inline void ceph_fscache_note_page_release(struct inode *inode)
60-
{
61-
struct ceph_inode_info *ci = ceph_inode(inode);
62-
63-
fscache_note_page_release(ceph_fscache_cookie(ci));
64-
}
6559
#else /* CONFIG_CEPH_FSCACHE */
6660
static inline int ceph_fscache_register_fs(struct ceph_fs_client* fsc,
6761
struct fs_context *fc)
@@ -118,10 +112,6 @@ static inline bool ceph_is_cache_enabled(struct inode *inode)
118112
{
119113
return false;
120114
}
121-
122-
static inline void ceph_fscache_note_page_release(struct inode *inode)
123-
{
124-
}
125115
#endif /* CONFIG_CEPH_FSCACHE */
126116

127117
#endif

fs/netfs/misc.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,45 @@ void netfs_clear_inode_writeback(struct inode *inode, const void *aux)
8484
}
8585
}
8686
EXPORT_SYMBOL(netfs_clear_inode_writeback);
87+
88+
/**
89+
* netfs_invalidate_folio - Invalidate or partially invalidate a folio
90+
* @folio: Folio proposed for release
91+
* @offset: Offset of the invalidated region
92+
* @length: Length of the invalidated region
93+
*
94+
* Invalidate part or all of a folio for a network filesystem. The folio will
95+
* be removed afterwards if the invalidated region covers the entire folio.
96+
*/
97+
void netfs_invalidate_folio(struct folio *folio, size_t offset, size_t length)
98+
{
99+
_enter("{%lx},%zx,%zx", folio_index(folio), offset, length);
100+
101+
folio_wait_fscache(folio);
102+
}
103+
EXPORT_SYMBOL(netfs_invalidate_folio);
104+
105+
/**
106+
* netfs_release_folio - Try to release a folio
107+
* @folio: Folio proposed for release
108+
* @gfp: Flags qualifying the release
109+
*
110+
* Request release of a folio and clean up its private state if it's not busy.
111+
* Returns true if the folio can now be released, false if not
112+
*/
113+
bool netfs_release_folio(struct folio *folio, gfp_t gfp)
114+
{
115+
struct netfs_inode *ctx = netfs_inode(folio_inode(folio));
116+
117+
if (folio_test_private(folio))
118+
return false;
119+
if (folio_test_fscache(folio)) {
120+
if (current_is_kswapd() || !(gfp & __GFP_FS))
121+
return false;
122+
folio_wait_fscache(folio);
123+
}
124+
125+
fscache_note_page_release(netfs_i_cookie(ctx));
126+
return true;
127+
}
128+
EXPORT_SYMBOL(netfs_release_folio);

include/linux/netfs.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,11 +293,13 @@ struct readahead_control;
293293
void netfs_readahead(struct readahead_control *);
294294
int netfs_read_folio(struct file *, struct folio *);
295295
int netfs_write_begin(struct netfs_inode *, struct file *,
296-
struct address_space *, loff_t pos, unsigned int len,
297-
struct folio **, void **fsdata);
296+
struct address_space *, loff_t pos, unsigned int len,
297+
struct folio **, void **fsdata);
298298
bool netfs_dirty_folio(struct address_space *mapping, struct folio *folio);
299299
int netfs_unpin_writeback(struct inode *inode, struct writeback_control *wbc);
300300
void netfs_clear_inode_writeback(struct inode *inode, const void *aux);
301+
void netfs_invalidate_folio(struct folio *folio, size_t offset, size_t length);
302+
bool netfs_release_folio(struct folio *folio, gfp_t gfp);
301303

302304
void netfs_subreq_terminated(struct netfs_io_subrequest *, ssize_t, bool);
303305
void netfs_get_subrequest(struct netfs_io_subrequest *subreq,

0 commit comments

Comments
 (0)