@@ -506,6 +506,7 @@ static int afs_releasepage(struct page *page, gfp_t gfp_flags)
return false;
wait_on_page_fscache(page);
}
+ fscache_note_page_release(afs_vnode_cache(vnode));
#endif
if (PagePrivate(page)) {
@@ -195,6 +195,7 @@ static void cachefiles_write_complete(struct kiocb *iocb, long ret, long ret2)
__sb_writers_acquired(inode->i_sb, SB_FREEZE_WRITE);
__sb_end_write(inode->i_sb, SB_FREEZE_WRITE);
+ set_bit(FSCACHE_COOKIE_HAVE_DATA, &ki->object->cookie->flags);
if (ki->term_func)
ki->term_func(ki->term_func_priv, ret, ki->was_async);
cachefiles_put_kiocb(ki);
@@ -263,6 +263,8 @@ static struct fscache_cookie *fscache_alloc_cookie(
cookie->key_len = index_key_len;
cookie->aux_len = aux_data_len;
cookie->object_size = object_size;
+ if (object_size == 0)
+ __set_bit(FSCACHE_COOKIE_NO_DATA_TO_READ, &cookie->flags);
if (fscache_set_key(cookie, index_key, index_key_len) < 0)
goto nomem;
@@ -131,6 +131,7 @@ struct fscache_cookie {
#define FSCACHE_COOKIE_DO_WITHDRAW 10 /* T if this cookie needs withdrawing */
#define FSCACHE_COOKIE_DO_COMMIT 11 /* T if this cookie needs committing */
#define FSCACHE_COOKIE_DO_PREP_TO_WRITE 12 /* T if cookie needs write preparation */
+#define FSCACHE_COOKIE_HAVE_DATA 13 /* T if this cookie has data stored */
enum fscache_cookie_stage stage;
u8 advice; /* FSCACHE_ADV_* */
@@ -643,7 +644,22 @@ static inline void fscache_clear_inode_writeback(struct fscache_cookie *cookie,
loff_t i_size = i_size_read(inode);
fscache_unuse_cookie(cookie, aux, &i_size);
}
+}
+/**
+ * fscache_note_page_release - Note that a netfs page got released
+ * @cookie: The cookie corresponding to the file
+ *
+ * Note that a page that has been copied to the cache has been released. This
+ * means that future reads will need to look in the cache to see if it's there.
+ */
+static inline
+void fscache_note_page_release(struct fscache_cookie *cookie)
+{
+ if (cookie &&
+ test_bit(FSCACHE_COOKIE_HAVE_DATA, &cookie->flags) &&
+ test_bit(FSCACHE_COOKIE_NO_DATA_TO_READ, &cookie->flags))
+ clear_bit(FSCACHE_COOKIE_NO_DATA_TO_READ, &cookie->flags);
}
#ifdef FSCACHE_USE_FALLBACK_IO_API
Drive the FSCACHE_COOKIE_NO_DATA_TO_READ bit to skip reads on cache files that can't have any data available to read. This needs clearing once we've written some data and then released the netfs page that contained it. Signed-off-by: David Howells <dhowells@redhat.com> --- fs/afs/file.c | 1 + fs/cachefiles/io.c | 1 + fs/fscache/cookie.c | 2 ++ include/linux/fscache.h | 16 ++++++++++++++++ 4 files changed, 20 insertions(+)