diff options
author | David Howells <dhowells@redhat.com> | 2020-02-06 14:22:29 +0000 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2021-04-23 10:17:28 +0100 |
commit | 3003bbd0697b659944237f3459489cb596ba196c (patch) | |
tree | 9549110fad53b5950e1a9ab5851268d48d5f8fdd /fs/afs/file.c | |
parent | 5cbf03985c67c7f0ac8c5382cf5d4d0d630f95f3 (diff) | |
download | linux-stable-3003bbd0697b659944237f3459489cb596ba196c.tar.gz linux-stable-3003bbd0697b659944237f3459489cb596ba196c.tar.bz2 linux-stable-3003bbd0697b659944237f3459489cb596ba196c.zip |
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.c | 19 |
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, }; |