summaryrefslogtreecommitdiff
path: root/fs/afs/file.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2020-02-06 14:22:29 +0000
committerDavid Howells <dhowells@redhat.com>2021-04-23 10:17:28 +0100
commit3003bbd0697b659944237f3459489cb596ba196c (patch)
tree9549110fad53b5950e1a9ab5851268d48d5f8fdd /fs/afs/file.c
parent5cbf03985c67c7f0ac8c5382cf5d4d0d630f95f3 (diff)
afs: Use the netfs_write_begin() helper
Make AFS use the new netfs_write_begin() helper to do the pre-reading required before the write. If successful, the helper returns with the required page filled in and locked. It may read more than just one page, expanding the read to meet cache granularity requirements as necessary. Note: A more advanced version of this could be made that does generic_perform_write() for a whole cache granule. This would make it easier to avoid doing the download/read for the data to be overwritten. Signed-off-by: David Howells <dhowells@redhat.com> Tested-By: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org cc: linux-cachefs@redhat.com cc: linux-fsdevel@vger.kernel.org Link: https://lore.kernel.org/r/160588546422.3465195.1546354372589291098.stgit@warthog.procyon.org.uk/ # rfc Link: https://lore.kernel.org/r/161539563244.286939.16537296241609909980.stgit@warthog.procyon.org.uk/ # v4 Link: https://lore.kernel.org/r/161653819291.2770958.406013201547420544.stgit@warthog.procyon.org.uk/ # v5 Link: https://lore.kernel.org/r/161789102743.6155.17396591236631761195.stgit@warthog.procyon.org.uk/ # v6
Diffstat (limited to 'fs/afs/file.c')
-rw-r--r--fs/afs/file.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/fs/afs/file.c b/fs/afs/file.c
index 10c6eaaac2cc..db035ae2a134 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -333,6 +333,13 @@ static void afs_init_rreq(struct netfs_read_request *rreq, struct file *file)
rreq->netfs_priv = key_get(afs_file_key(file));
}
+static bool afs_is_cache_enabled(struct inode *inode)
+{
+ struct fscache_cookie *cookie = afs_vnode_cache(AFS_FS_I(inode));
+
+ return fscache_cookie_enabled(cookie) && !hlist_empty(&cookie->backing_objects);
+}
+
static int afs_begin_cache_operation(struct netfs_read_request *rreq)
{
struct afs_vnode *vnode = AFS_FS_I(rreq->inode);
@@ -340,14 +347,24 @@ static int afs_begin_cache_operation(struct netfs_read_request *rreq)
return fscache_begin_read_operation(rreq, afs_vnode_cache(vnode));
}
+static int afs_check_write_begin(struct file *file, loff_t pos, unsigned len,
+ struct page *page, void **_fsdata)
+{
+ struct afs_vnode *vnode = AFS_FS_I(file_inode(file));
+
+ return test_bit(AFS_VNODE_DELETED, &vnode->flags) ? -ESTALE : 0;
+}
+
static void afs_priv_cleanup(struct address_space *mapping, void *netfs_priv)
{
key_put(netfs_priv);
}
-static const struct netfs_read_request_ops afs_req_ops = {
+const struct netfs_read_request_ops afs_req_ops = {
.init_rreq = afs_init_rreq,
+ .is_cache_enabled = afs_is_cache_enabled,
.begin_cache_operation = afs_begin_cache_operation,
+ .check_write_begin = afs_check_write_begin,
.issue_op = afs_req_issue_op,
.cleanup = afs_priv_cleanup,
};